美文网首页
RN-自定义下拉选择框

RN-自定义下拉选择框

作者: 精神病患者link常 | 来源:发表于2020-11-18 11:14 被阅读0次
image.png

思路:

1.按钮点击,计算出按钮的位置大小信息,得到相对于屏幕的位置。
2.计算出以后显示一个modal,根据按钮的位置信息在下方显示下拉框View

如果想要实现下拉框随着页面滚动,先计算按钮的位置信息,然后绝对定位ViewScrollView上。

所有代码

import React, {  Component } from 'react';

import {
  StyleSheet,
  View,
  TouchableOpacity,
  Modal,
  TouchableWithoutFeedback,
  ScrollView,
  Text,
} from 'react-native';
import * as c from '../../common/ScreenUtil';

const itemHeight = 30
const maxCount =  5

/**
 * 
 * @param props:{
 * options:array(数据源)
 * itemHeight:number(下拉框item的高度)
 * onChoose:func (item点击触发事件)(index)
 * renderRow:func(外部传入item组件,方便自己定义)(index,onDismiss),存在时 options 无用
 *    index:当前组件的数据源下标
 *    onDismiss:renderRow点击时的回调,用于内部进行隐藏
 * }
 */
function DropdownButton(props){

  const [isShowModal,setIsShowModal] = React.useState(false)
  const [buttonFrame,setButtonFrame] = React.useState({})
  const [dropDownViewHeight,setDropDownViewHeight] = React.useState(0)

  const dropDownButton = React.useRef(null);

  function onButtonClick(){

    dropDownButton.current.measure((fx, fy, width, height, px, py) => {
      setButtonFrame({px, py, width, height})
      setDropDownViewHeight((props.options ? (props.options.length > maxCount ? maxCount : props.options.length) : 0) * (props.itemHeight || itemHeight))
      setIsShowModal(true)
    });
  }

  function onChooseClick(index){
    props.onChoose && props.onChoose(index)
    onDismiss()
  }

  function onDismiss(){
    setIsShowModal(false)
    setDropDownViewHeight(0)
  }

  return <TouchableOpacity {...props} ref={dropDownButton} onPress={onButtonClick}>
    {
        React.Children.map(props.children, function (child) {
          return child;
        })
    }
    {
      isShowModal && buttonFrame.py && <Modal
        animationType={'fade'}
        visible={true}
        transparent={true}
        onRequestClose={()=>{}}>
        <TouchableOpacity style={styles.modalBtn} activeOpacity={1} onPress={onDismiss}>
          <View style={[styles.optionsView,{
            width:buttonFrame.width || 0,
            height:dropDownViewHeight,
            marginLeft:buttonFrame.px,
            marginTop:buttonFrame.py + buttonFrame.height
            },props.itemViewStyle || {}]}>
          <ScrollView>
            {
              props.options && props.options.map((item,index)=>{
                if (props.renderRow){
                  return props.renderRow(index,onDismiss)
                }
                return <TouchableOpacity key={index} style={{height:props.itemHeight || itemHeight}} onPress={()=>onChooseClick(index)}>
                  <Text>{item}</Text>
                </TouchableOpacity>
              })
            }
          </ScrollView>
          </View>
        </TouchableOpacity>
      </Modal>
    }
  </TouchableOpacity>
}

const styles = StyleSheet.create({
  modalBtn: {
    backgroundColor:'transparent',
    width:c.screenW,
    height:c.screenH
  },
  optionsView:{
    backgroundColor:'purple'
  }
})
export default DropdownButton

使用

默认item

<DropdownButton style={{flex:1,backgroundColor:'purple'}} options={[
  "祖安狂人",
  "扭曲丛林",
  "德玛西亚"
]} onChoose={(index)=>{

}}>
  <Text style={{marginVertical:10}}>祖安狂人</Text>
</DropdownButton>

自定义item

<DropdownButton style={{flex:1,backgroundColor:'purple'}} 
  onChoose={(index)=>{

  }} renderRow={(index,onDismiss)=>{
    return <TouchableOpacity onPress={()=>{
      // do something
      onDismiss()
    }}>
      <Text>{index}</Text>
    </TouchableOpacity>
  }}>
  <Text style={{marginVertical:10}}>祖安狂人</Text>
</DropdownButton>

相关文章

网友评论

      本文标题:RN-自定义下拉选择框

      本文链接:https://www.haomeiwen.com/subject/csoqiktx.html