image.png
思路:
1.按钮点击,计算出按钮的位置大小信息,得到相对于屏幕的位置。
2.计算出以后显示一个modal,根据按钮的位置信息在下方显示下拉框View
如果想要实现下拉框随着页面滚动,先计算按钮的位置信息,然后绝对定位View到ScrollView上。
所有代码
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
{
React.Children.map(props.children, function (child) {
return child;
})
}
{
isShowModal && buttonFrame.py &&
animationType={'fade'}
visible={true}
transparent={true}
onRequestClose={()=>{}}>
width:buttonFrame.width || 0,
height:dropDownViewHeight,
marginLeft:buttonFrame.px,
marginTop:buttonFrame.py + buttonFrame.height
},props.itemViewStyle || {}]}>
{
props.options && props.options.map((item,index)=>{
if (props.renderRow){
return props.renderRow(index,onDismiss)
}
return onChooseClick(index)}>
{item}
})
}
}
}
const styles = StyleSheet.create({
modalBtn: {
backgroundColor:'transparent',
width:c.screenW,
height:c.screenH
},
optionsView:{
backgroundColor:'purple'
}
})
export default DropdownButton
使用
默认item
"祖安狂人",
"扭曲丛林",
"德玛西亚"
]} onChoose={(index)=>{
}}>
祖安狂人
自定义item
onChoose={(index)=>{
}} renderRow={(index,onDismiss)=>{
return {
// do something
onDismiss()
}}>
{index}
}}>
祖安狂人