react-native 封装选择弹出框示例(试用ios&android)

yizhihongxing

下面是关于"react-native 封装选择弹出框示例(试用ios&android)"的完整攻略。

1. 简介

本篇攻略将介绍如何封装一个React Native的选择弹出框组件,并提供两个具体实例以及对应的完整代码。

2. 需求分析

在实际的开发过程中,选择弹出框是一个经常使用的UI组件。因此,我们需要封装这个组件,使得以后在开发中可以方便地使用它。

以下是选择弹出框的需求分析:

  1. 组件需要在ios和android下都能正常工作;
  2. 组件需要支持单选和多选两种模式;
  3. 组件需要支持传入选择项的数据源;
  4. 组件需要支持外部自定义布局;
  5. 组件需要支持选择完成后的回调函数。

根据以上需求,我们可以开始着手实现这个组件。

3. 实现过程

3.1 创建选择弹出框组件SelectModal

我们可以通过继承官方的Modal组件来实现选择弹出框组件。首先,我们需要在项目中创建一个名为SelectModal的文件夹,并在其中创建index.js文件和styles.js文件,代码如下:

// index.js
import React, {Component} from 'react';
import {View, Text, Button, Modal, TouchableOpacity, StyleSheet} from 'react-native';

class SelectModal extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return <View></View>;
  }
}

export default SelectModal;

// styles.js
import {StyleSheet} from 'react-native';

export default StyleSheet.create({
  container: {
    flex: 1,
  },
});

注意,由于我们需要用到Modal和TouchableOpacity等官方组件,因此在文件开头需要对它们进行引入。

接下来,我们需要在SelectModal类中实现选择弹出框组件的主要功能。这里仅给出完整代码,详细讲解将放在后面的示例中。最终,SelectModal组件的代码如下:

// index.js
import React, {Component} from 'react';
import {
  View,
  Text,
  Button,
  Modal,
  TouchableOpacity,
  StyleSheet,
} from 'react-native';

class SelectModal extends Component {
  constructor(props) {
    super(props);

    this.state = {
      visible: false, // 是否显示
      selectMode: 'single', // 'single' / 'multiple'
      selectedIndex: [], // 已选择的选项索引数组
    };
  }

  setSelectedIndex(index) {
    let {selectMode, selectedIndex} = this.state;
    if (selectMode === 'single') {
      // 单选
      this.setState({
        visible: false,
        selectedIndex: [index],
      });
    } else {
      // 多选
      selectedIndex = selectedIndex.slice();
      if (selectedIndex.includes(index)) {
        // 当前项已经被选中,删除
        selectedIndex.splice(selectedIndex.indexOf(index), 1);
      } else {
        // 当前项未被选中,添加
        selectedIndex.push(index);
      }
      this.setState({
        visible: false,
        selectedIndex,
      });
    }

    // 调用外部回调函数
    if (this.props.onSelect) {
      setTimeout(() => {
        this.props.onSelect(selectedIndex);
      }, 100);
    }
  }

  render() {
    let {visible, selectMode, selectedIndex} = this.state;
    let {data, renderItem, renderItemText, title, cancelText, confirmText} =
      this.props;

    return (
      <Modal visible={visible} transparent={true} animationType="fade">
        <TouchableOpacity
          activeOpacity={1}
          style={styles.container}
          onPress={() => {
            this.setState({
              visible: false,
            });
          }}>
          <View style={styles.content}>
            <View style={styles.titleContainer}>
              <Text style={styles.titleText}>{title}</Text>
            </View>
            <View style={styles.itemContainer}>
              {data.map((item, index) => {
                let selected = selectedIndex.includes(index);
                let renderItemUI = renderItem
                  ? renderItem(item, selected)
                  : null;

                if (!renderItemUI) {
                  renderItemUI = (
                    <View
                      style={[
                        styles.item,
                        selected ? styles.selectedItem : null,
                      ]}
                      key={index}>
                      <Text style={styles.itemText}>{item}</Text>
                      {selected ? (
                        <View style={styles.selectedIcon} />
                      ) : null}
                    </View>
                  );
                }

                return (
                  <TouchableOpacity
                    activeOpacity={1}
                    onPress={() => {
                      this.setSelectedIndex(index);
                    }}
                    key={index}>
                    {renderItemUI}
                  </TouchableOpacity>
                );
              })}
            </View>
            <View style={styles.btnContainer}>
              <TouchableOpacity
                activeOpacity={0.8}
                style={styles.cancelBtn}
                onPress={() => {
                  this.setState({
                    visible: false,
                  });
                }}>
                <Text style={styles.btnText}>{cancelText}</Text>
              </TouchableOpacity>
              <TouchableOpacity
                activeOpacity={0.8}
                style={styles.confirmBtn}
                onPress={() => {
                  this.setSelectedIndex(selectedIndex);
                }}>
                <Text style={styles.btnText}>{confirmText}</Text>
              </TouchableOpacity>
            </View>
          </View>
        </TouchableOpacity>
      </Modal>
    );
  }
}

SelectModal.defaultProps = {
  data: [], // 数据源
  renderItem: null, // 渲染自定义选项UI的函数
  renderItemText: null, // 渲染选项文本的函数
  title: '', // 标题
  cancelText: '取消', // 取消按钮文本
  confirmText: '确定', // 确定按钮文本
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.5)',
    justifyContent: 'center',
    alignItems: 'center',
  },
  content: {
    backgroundColor: 'white',
    borderRadius: 10,
    width: '80%',
  },
  titleContainer: {
    height: 50,
    justifyContent: 'center',
    alignItems: 'center',
    borderBottomWidth: 1,
    borderBottomColor: '#F0F0F0',
  },
  titleText: {
    fontSize: 18,
    fontWeight: 'bold',
  },
  itemContainer: {
    maxHeight: 300,
  },
  item: {
    padding: 10,
  },
  itemText: {
    fontSize: 16,
    color: '#333',
  },
  selectedItem: {
    backgroundColor: '#F0F0F0',
  },
  selectedIcon: {
    position: 'absolute',
    top: 10,
    right: 10,
    width: 12,
    height: 12,
    borderRadius: 6,
    backgroundColor: '#3F51B5',
  },
  btnContainer: {
    borderTopWidth: 1,
    borderTopColor: '#F0F0F0',
    flexDirection: 'row',
    justifyContent: 'flex-end',
  },
  cancelBtn: {
    width: 80,
    height: 50,
    justifyContent: 'center',
    paddingLeft: 10,
    paddingRight: 10,
  },
  confirmBtn: {
    width: 80,
    height: 50,
    justifyContent: 'center',
    paddingLeft: 10,
    paddingRight: 10,
  },
  btnText: {
    fontSize: 16,
    color: '#3F51B5',
  },
});

export default SelectModal;

可以看到,SelectModal组件的代码已经完成了全部实现,包括Modal的显示和隐藏、单选和多选功能、自定义布局、回调函数等。

3.2 使用SelectModal组件

下面我们将分别给出两个具体的使用示例。

3.2.1 示例一:总统选举

在这个示例中,我们将使用SelectModal组件来演示一个总统选举的投票流程。假设投票人可以选择一位总统候选人进行投票,投票结果将在弹出框标题上显示。完整代码如下:

import React, {Component} from 'react';
import {View, Text, TouchableOpacity} from 'react-native';

import SelectModal from './SelectModal';

class Example1 extends Component {
  constructor(props) {
    super(props);

    this.state = {
      selectedIndex: [], // 已选择的候选人索引数组
    };
  }

  render() {
    let {selectedIndex} = this.state;

    return (
      <View style={{flex: 1}}>
        <TouchableOpacity
          activeOpacity={0.8}
          onPress={() => {
            this.setState({
              modalVisible: true,
            });
          }}>
          <View style={{height: 50, justifyContent: 'center'}}>
            <Text>
              {selectedIndex.length > 0
                ? '你已经选择了' + (selectedIndex[0] + 1) + '号候选人'
                : '请选择一位总统候选人'}
            </Text>
          </View>
        </TouchableOpacity>

        <SelectModal
          visible={this.state.modalVisible}
          data={['候选人1', '候选人2', '候选人3']}
          onSelect={(selectedIndex) => {
            this.setState({
              modalVisible: false,
              selectedIndex,
            });
          }}
          title="总统选举"
          cancelButtonText="取消"
          confirmButtonText="确定"
        />
      </View>
    );
  }
}

export default Example1;

以上代码实现了一个简单的投票系统,当点击文本框时,选择弹出框组件将显示,用户可以选择喜欢的候选人进行投票。投票完成后,选择弹出框组件会自动隐藏,并将选择的结果显示在文本框的文本上。代码中的data属性定义了三个候选人,分别对应了三个投票选项。

3.2.2 示例二:星座配对

在这个示例中,我们将使用SelectModal组件来演示一个星座配对的小游戏。假设用户可以从两个弹出框中选择自己和匹配对象的星座,系统将自动根据选择的星座生成配对结果。完整代码如下:

import React, {Component} from 'react';
import {View, Text, TouchableOpacity} from 'react-native';

import SelectModal from './SelectModal';

class Example2 extends Component {
  constructor(props) {
    super(props);

    this.state = {
      selectedStarIndex1: [], // 已选择的星座1索引数组
      selectedStarIndex2: [], // 已选择的星座2索引数组
    };
  }

  getResult() {
    let starNames = [
      '白羊座',
      '金牛座',
      '双子座',
      '巨蟹座',
      '狮子座',
      '处女座',
      '天秤座',
      '天蝎座',
      '射手座',
      '摩羯座',
      '水瓶座',
      '双鱼座',
    ];

    let getResultByStars = (star1, star2) => {
      let index1 = starNames.indexOf(star1);
      let index2 = starNames.indexOf(star2);
      let resultIndex = (index1 + index2) % 12;
      return starNames[resultIndex];
    };

    let {selectedStarIndex1, selectedStarIndex2} = this.state;
    let star1 =
      selectedStarIndex1.length > 0 ? starNames[selectedStarIndex1[0]] : '';
    let star2 =
      selectedStarIndex2.length > 0 ? starNames[selectedStarIndex2[0]] : '';
    let result = getResultByStars(star1, star2);

    return result;
  }

  render() {
    let result = this.getResult();

    return (
      <View style={{flex: 1}}>
        <TouchableOpacity
          activeOpacity={0.8}
          onPress={() => {
            this.setState({
              modalVisible1: true,
            });
          }}>
          <View style={{height: 50, justifyContent: 'center'}}>
            <Text>
              {this.state.selectedStarIndex1.length > 0
                ? '你选择的星座是' +
                  [
                    '白羊座',
                    '金牛座',
                    '双子座',
                    '巨蟹座',
                    '狮子座',
                    '处女座',
                    '天秤座',
                    '天蝎座',
                    '射手座',
                    '摩羯座',
                    '水瓶座',
                    '双鱼座',
                  ][this.state.selectedStarIndex1[0]]
                : '请选择自己的星座'}
            </Text>
          </View>
        </TouchableOpacity>
        <TouchableOpacity
          activeOpacity={0.8}
          onPress={() => {
            this.setState({
              modalVisible2: true,
            });
          }}>
          <View style={{height: 50, justifyContent: 'center'}}>
            <Text>
              {this.state.selectedStarIndex2.length > 0
                ? '你选择的星座是' +
                  [
                    '白羊座',
                    '金牛座',
                    '双子座',
                    '巨蟹座',
                    '狮子座',
                    '处女座',
                    '天秤座',
                    '天蝎座',
                    '射手座',
                    '摩羯座',
                    '水瓶座',
                    '双鱼座',
                  ][this.state.selectedStarIndex2[0]]
                : '请选择另一半的星座'}
            </Text>
          </View>
        </TouchableOpacity>
        {this.state.selectedStarIndex1.length > 0 &&
        this.state.selectedStarIndex2.length > 0 ? (
          <View style={{flex: 1, justifyContent: 'center'}}>
            <Text style={{fontSize: 24}}>你们的星座配对结果是</Text>
            <Text style={{fontSize: 36}}>{result}</Text>
          </View>
        ) : (
          <View style={{height: 300}}></View>
        )}

        <SelectModal
          visible={this.state.modalVisible1}
          data={[
            '白羊座',
            '金牛座',
            '双子座',
            '巨蟹座',
            '狮子座',
            '处女座',
            '天秤座',
            '天蝎座',
            '射手座',
            '摩羯座',
            '水瓶座',
            '双鱼座',
          ]}
          onSelect={(selectedStarIndex1) => {
            this.setState({
              modalVisible1: false,
              selectedStarIndex1,
            });
          }}
          title="请选择你的星座"
          cancelButtonText="取消"
          confirmButtonText="确定"
        />
        <SelectModal
          visible={this.state.modalVisible2}
          data={[
            '白羊座',
            '金牛座',
            '双子座',
            '巨蟹座',
            '狮子座',
            '处女座',
            '天秤座',
            '天蝎座',
            '射手座',
            '摩羯座',
            '水瓶座',
            '双鱼座',
          ]}
          onSelect={(selectedStarIndex2) => {
            this.setState({
              modalVisible2: false,
              selectedStarIndex2,
            });
          }}
          title="请选择另一半的星座"
          cancelButtonText="取消"
          confirmButtonText="确定"
        />
      </View>
    );
  }
}

export default Example2;

以上代码实现了一个简单的星座配对小游戏,用户可以在两个弹出框中选择自己和另一半的星座。当两个选择框都有选择时,程序会自动根据选定的星座计算配对结果,并将结果显示在页面下方。在代码中,getResult函数即为计算配对结果的函数。

4. 结语

通过以上两个示例,我们可以看到如何封装一个选择弹出框组件,并对其进行简单的定制和使用。在实际的开发过程中,我们可以根据具体需求对组件代码进行修改,从而得到一个更符合自己需求的组件。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:react-native 封装选择弹出框示例(试用ios&android) - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • 解决”恢复我的工作并重启word”的多种方法介绍

    当我们在使用Word编辑文档时,有时会遇到Word软件崩溃或中断的情况,导致正在编辑的文档丢失或无法打开。本文将介绍多种方法来解决这个问题。 方法一:使用自动恢复功能来重启Word 重新启动Word 在恢复窗口中,选择您需要恢复的文件 单击“恢复”按钮使文件恢复完毕 请注意:Word 会自动启用恢复文件选项,因此如果您打开Word前已选择自动保存选项,则您可…

    other 2023年6月27日
    00
  • 使用 Java 开发 Gradle 插件的步骤

    使用 Java 开发 Gradle 插件的步骤 Gradle 是一个强大的构建工具,它允许开发者使用 Java 开发自定义的 Gradle 插件。下面是使用 Java 开发 Gradle 插件的完整步骤: 步骤一:创建 Gradle 项目 首先,我们需要创建一个 Gradle 项目来开发我们的插件。可以按照以下步骤创建一个新的 Gradle 项目: 打开终端…

    other 2023年7月27日
    00
  • Java向上转型和向下转型的区别说明

    Java中的向上转型(upcasting)和向下转型(downcasting)是针对于基础数据类型之外的类和对象而言的。 向上转型 向上转型是指从一个子类引用转换为其父类引用的过程,这种转化是自动完成的。在向上转型的过程中,实际所指向的对象为子类对象,但只能使用父类中定义的方法和属性。 下面是一个示例: public class Animal { publi…

    other 2023年6月26日
    00
  • Go语言中map使用和并发安全详解

    Go语言中map使用和并发安全详解 概述 在Go语言中,map是一种集合类型,它可以关联一个键和一个值。map是一种引用类型,可以使用 make 函数来创建。map 的底层实现是 hash 表,因此 map 的键是无序的,但是在迭代过程中,Go语言会自动对其进行排序。 map 的基本使用方法是:使用键访问值,如果键不存在,则会返回初始值。map 与 slic…

    other 2023年6月26日
    00
  • Angular中ng-template和ng-container的应用小结

    当然!下面是关于\”Angular中ng-template和ng-container的应用小结\”的完整攻略,包含两个示例说明。 … … … … 示例1:使用ng-template进行条件渲染 <ng-template [ngIf]=\"showMessage\"> <p>显示的消息</p&g…

    other 2023年8月20日
    00
  • buildbot入门系列—介绍篇

    Buildbot是一款开源的持续集成(CI)工具,可以自动化构建、测试和部署软件项目。本文将深入介绍Buildbot的入门知识,包括Buildbot基本概念、架构和使用方法,并提供两个示例说明。 Buildbot的基本概念 Master和Worker Buildbot的架构由Master和Worker两部分组成。Master是Buildbot的核心,负责管理…

    other 2023年5月8日
    00
  • es6英文文档翻译

    es6英文文档翻译 作为 JavaScript 的一种标准,ES6 在语言特性上做出了很多改进和扩展,例如新增了箭头函数、模板字符串、解构赋值、对象扩展等特性,大大提升了开发效率和代码可读性。 为了更好地学习和使用 ES6,在这里提供 ES6 文档的翻译。以下是部分内容的翻译示例。 变量声明 ES6 中新增了两个关键字 let 和 const,用以声明块级作…

    其他 2023年3月28日
    00
  • 使用delphi 10.2 开发linux 上的webservice

    使用Delphi 10.2在Linux上开发WebService 随着云计算和分布式系统的兴起,Web服务已经成为了重要的技术之一。在Delphi 10.2中开发Linux上的WebService可以为我们带来许多便利,本文将介绍使用Delphi 10.2开发Linux上的WebService的基本流程。 准备工作 在开始之前,我们需要确保我们已经正确安装了…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部