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

下面是关于"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日

相关文章

  • Android蓝牙开发深入解析

    Android蓝牙开发深入解析 本篇文章旨在为读者提供与Android蓝牙开发相关的深入解析。文章包括了如下内容: 蓝牙基础知识 蓝牙开发流程 实现蓝牙连接 数据传输 示例说明 蓝牙基础知识 蓝牙协议栈 Android蓝牙协议栈分为两个层次: Bluetooth Manager Service层:该层提供了上层应用程序与底层硬件之间的接口,使用Bluetoo…

    other 2023年6月27日
    00
  • 一文彻底理解JavaScript原型与原型链

    下面就是详细讲解“一文彻底理解JavaScript原型与原型链”的完整攻略: 一、JavaScript中的原型 JavaScript中的原型(prototype)是指每个函数都有一个prototype属性,它是一个指向对象的指针。prototype指针所指向的对象被称为原型对象。 1.1 构造函数与原型 当一个函数用来作为构造函数时,它所创建的对象都有一个隐…

    other 2023年6月26日
    00
  • 微信小程序实现循环嵌套数据选择

    type: Array, value: [], }, }, methods: { handleChange(e) { const { value } = e.detail; const selectedItem = this.data.data[value]; const { children } = selectedItem; if (children &…

    other 2023年7月27日
    00
  • markdown数学符号数学表达式,绝对有你想要的

    Markdown数学符号数学表达式攻略 Markdown是一种轻量级标记语言,它支持使用数学符号和数学表达式。本攻略将详细介绍如何在Markdown中使用数学符号和数学表达式,并提供两个示例。 数学符号 Markdown支持使用LaTeX语法来插入数学符号。以下是一些常用的数学符号及其LaTeX语法: 加号:$+$ 减号:$-$ 乘号:$\times$ 除号…

    other 2023年5月9日
    00
  • microsoftsynctoy文件同步工具

    Microsoft SyncToy 文件同步工具 文件同步工具在日常生活和工作中有着不可替代的作用。Microsoft SyncToy 是微软推出的一款能够进行文件同步和备份的工具。本文将详细介绍 Microsoft SyncToy 的使用方法和注意事项。 下载和安装 Microsoft SyncToy 是免费提供的,您可以在官方网站(https://www…

    其他 2023年3月29日
    00
  • 初窥Linux 之我最常用的20条命令总结

    下面我来详细讲解一下“初窥Linux 之我最常用的20条命令总结”的完整攻略。 登录Linux系统 在终端输入ssh [用户]@[主机名]即可登录Linux系统,其中[用户]是你的用户名,[主机名]是你要连接的主机名或IP地址。 示例: ssh username@192.168.1.10 创建文件夹 使用mkdir命令可以创建一个新的文件夹,例如: mkdi…

    other 2023年6月26日
    00
  • IDE – vscode

    IDE – vscode IDE是Integrated Development Environment的缩写,即集成开发环境。它是一个包含代码编辑器、编译器、调试器等多种开发工具的软件应用程序,为程序员提供了尽可能的便利。 在众多的IDE工具中,vscode无疑是一个备受好评的开源IDE。它基于Electron框架开发,由微软推出,支持多种编程语言,如Jav…

    其他 2023年3月28日
    00
  • 魔兽世界wlk怀旧服防战堆什么属性 防战属性优先级选择攻略

    魔兽世界Wlk怀旧服防战属性优先级选择攻略 简介 在魔兽世界怀旧服中,防战(Protection Warrior)是一个非常重要的职业角色。防战的任务是保护团队并吸引敌人的攻击。选择合适的属性和装备是确保防战在战斗中保持高效的关键。 属性优先级选择攻略 1. 耐力(Stamina) 耐力是防战最重要的属性之一,因为它直接决定了防战的生存能力。耐力提供额外的生…

    other 2023年6月28日
    00
合作推广
合作推广
分享本页
返回顶部