当前位置: 首页 > news >正文

reactnative下拉选择

reactnative下拉选择

引用

<FilterDropdownlabel={""}options={this.state.recordListType}value={this.state.recordType}onChange={(item) => this.handleRecordTypeChange(item)}leftIcon={recordSimg}width={'100%'}style={{ width: "100%", color: 'red' }}labelKey="label"valueKey="value"/>

代码组件

import React, { useState, useRef } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, Image, Modal } from 'react-native';/*** 通用下拉筛选组件(横向筛选栏专用,菜单用Modal渲染)* @param {string} label - 按钮显示文字* @param {array} options - 选项数组(字符串数组或对象数组)* @param {string|object} value - 当前选中值* @param {function} onChange - 选中项变化回调* @param {number} width - 按钮宽度(可选)* @param {string} labelKey - 对象数组中用于显示的字段名(可选,默认为'label')* @param {string} valueKey - 对象数组中用于值的字段名(可选,默认为'value')* @param {string} displayKey - 按钮显示文字的字段名(可选,默认为'label')*/
const FilterDropdown = ({label = '',options = [],value = '',onChange = () => {}, // 默认空函数width = zero.yWidth(100),leftIcon,disabled = false,style = {}, // 新增,接收外部stylelabelKey = 'label', // 对象数组中用于显示的字段名valueKey = 'value', // 对象数组中用于值的字段名displayKey = 'label', // 按钮显示文字的字段名
}) => {const [visible, setVisible] = useState(false);const btnRef = useRef();const [btnLayout, setBtnLayout] = useState({ x: 0, y: 0, width: width, height: zero.yHeight(32) });// 判断是否为对象数组const isObjectArray = options.length > 0 && typeof options[0] === 'object';// 获取显示文本const getDisplayText = (item) => {if (isObjectArray) {return item[displayKey] || item[labelKey] || '';}return item;};// 获取选项值const getOptionValue = (item) => {if (isObjectArray) {return item[valueKey] || item[labelKey] || '';}return item;};// 获取当前选中项的显示文本const getCurrentDisplayText = () => {if (!value) return label;if (isObjectArray) {const selectedOption = options.find(option => getOptionValue(option) === value);return selectedOption ? getDisplayText(selectedOption) : label;}return value;};// 记录按钮宽度和位置,菜单宽度与按钮对齐const handleBtnLayout = (e) => {if (btnRef.current) {btnRef.current.measureInWindow((x, y, width, height) => {setBtnLayout({ x, y, width, height });});}};return (<View style={[styles.wrap, style]}><TouchableOpacityref={btnRef}style={[styles.btn, value ? styles.btnActive : null, { width }]}activeOpacity={0.8}onPress={() => {if (disabled) returnhandleBtnLayout();setVisible(!visible);}}><View style={{ flexDirection: 'row', alignItems: 'center' }}>{leftIcon && (<Imagesource={leftIcon}style={[styles.leftIcon]}/>)}<Text style={[styles.btnText, value ? styles.btnTextActive : null]}>{getCurrentDisplayText()}</Text></View><Imagesource={visible ? require('../res/arrowup.png') : require('../res/arrowdown.png')}style={[styles.arrowIcon]}/></TouchableOpacity><Modalvisible={visible}transparentanimationType="fade"onRequestClose={() => setVisible(false)}><TouchableOpacitystyle={styles.modalMask}activeOpacity={1}onPress={() => setVisible(false)}><View style={[styles.dropdown,{position: 'absolute',left: btnLayout.x,top: btnLayout.y + btnLayout.height,width: btnLayout.width,}]}>{options.map((opt, idx) => {const optionValue = getOptionValue(opt);const optionText = getDisplayText(opt);const isSelected = isObjectArray ? optionValue === value : opt === value;return (<React.Fragment key={optionValue || idx}><TouchableOpacitystyle={styles.option}onPress={() => {setVisible(false);onChange && onChange(optionValue, opt);}}><Text style={[styles.optionText, isSelected && styles.optionTextActive]}>{optionText}</Text></TouchableOpacity>{idx !== options.length - 1 && <View style={styles.divider} />}</React.Fragment>);})}</View></TouchableOpacity></Modal></View>);
};const styles = StyleSheet.create({wrap: {position: 'relative',marginRight: zero.yWidth(8),justifyContent: 'space-between',zIndex: 10,// width: zero.yWidth(87), // 移除固定宽度// height: zero.yHeight(29.43), // 移除固定高度},btn: {flexDirection: 'row',alignItems: 'center',backgroundColor: '#F5F7FA',borderRadius: zero.yHeight(10),paddingHorizontal: zero.yWidth(10),height: zero.yHeight(32),borderWidth: 1,borderColor: 'transparent',minWidth: zero.yWidth(70),justifyContent: 'space-between',},btnActive: {// borderColor: '#1890FF',// backgroundColor: '#E6F0FF',},btnText: {color: '#222',fontSize: zero.yFont(15),},btnTextActive: {color: '#000000',fontWeight: 'bold',},leftIcon:{width: zero.yWidth(18),height: zero.yHeight(18),marginRight:zero.yWidth(15),resizeMode: 'contain',},arrowIcon: {width: zero.yWidth(9.19),height: zero.yHeight(5.89),marginLeft: zero.yWidth(4),tintColor: '#1890FF',resizeMode: 'contain',transform: [{ rotate: '0deg' }],},arrowIconUp: {transform: [{ rotate: '180deg' }],},arrowActive: {tintColor: '#1890FF',},modalMask: {flex: 1,backgroundColor: 'rgba(0,0,0,0.1)',},dropdown: {backgroundColor: '#fff',borderRadius: zero.yHeight(10),shadowColor: '#000',shadowOffset: { width: 0, height: 2 },shadowOpacity: 0.08,shadowRadius: zero.yHeight(8),elevation: zero.yHeight(8),minWidth: zero.yWidth(80),overflow: 'hidden',},option: {paddingVertical: zero.yHeight(12),paddingHorizontal: zero.yWidth(20),backgroundColor: '#fff',},optionText: {color: '#222',fontSize: zero.yFont(15),textAlign: 'left',},optionTextActive: {color: '#1890FF',fontWeight: 'bold',},divider: {height: zero.yHeight(1),backgroundColor: '#F0F0F0',marginHorizontal: zero.yWidth(10),},
});export default FilterDropdown;
http://www.dtcms.com/a/554573.html

相关文章:

  • 操作系统基础·3 进程线程模型
  • CTFHub XSS通关2:存储型
  • 递归专题3 - 回溯算法十大类型
  • python全栈-数据分析软件tableau的使用
  • 交流电里的电子咋流动?不是往前跑,而是来回 “晃”
  • 做网站写代码怎么样免费网站建设基础步骤
  • 网站.cc域名网站常见结构有那些
  • 网上做兼职老师的正规网站搭建网站的步骤有哪些
  • python进阶教程10:面向对象、super()和元类
  • 大同建设银行保安招聘网站商品展示的网站源码
  • 中交建设集团 网站win10系统可以做网站搭建
  • 做网站建设怎么介绍自己网页图片文字识别
  • 内部类和Object类
  • B049基于博途西门子1200PLC红绿灯控制系统仿真
  • 淘宝手机网站模板下载安装公司网站模板大全
  • 专属虚拟环境:Hugging Face数据集批量下载(无登录+国内加速)完整指南
  • 域名访问网站应该怎么做高端网站建设济南兴田德润简介电话
  • **新一代券商与机构专业交易系统开发:从国际金融变局到技术架构重构**
  • 最好网站建设公司哪家好阳泉集团网站建设
  • 电子商务网站怎么做素材包wordpress 浮窗
  • 海东企业网站建设公司南村网站建设
  • 宁波市高等级公路建设指挥部网站扁平化设计网站
  • e建网站网站设置访问权限
  • 查找(无序线性、有序线性、二分查找)
  • 不同规模企业如何选择与进化营销费用管理?
  • 备案期间网站中小企业
  • .gitignore配置了忽略dist文件夹,但是souretree还是跟踪了dist文件夹的变化怎么解决
  • 网站开发总出现出现404做网站有哪些技术
  • 突破协议壁垒:CCLINK转EtherNet/IP在大型温室罗克韦尔PLC伺服通讯中的实践
  • edu网站一般谁做的网站的seo怎么做