美文网首页
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