博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ReactNative学习笔记--下拉选择菜单的简单封装
阅读量:4086 次
发布时间:2019-05-25

本文共 5476 字,大约阅读时间需要 18 分钟。

ReactNative 学习笔记--封装下拉菜单

单个下拉子项

先看整体要做的效果

1.实现原理:

先做一行按钮,使我们要点击弹出菜单列表的按钮,然后计算点击的按钮所在的位置,再通过点击按钮的高度计算出要弹出列表的位置和宽度高度等,利用绝对布局在Modal组件上显示,并设置对应的效果,例如'fade',弹出的Modal覆盖整个界面,选择列表子项或者点击其他位置(Modal上)都要让Modal消失,再次点击按钮的时候,显示下拉菜单前重新计算对应按钮的位置和点击按钮对应的下拉菜单的位置,然后重新更改下拉菜单的位置和内容并显示,后面就按这个逻辑。

2.实现代码

分两步:

单个子项 SiftListItem

先看render了解整体布局

render() {
return (
{
this._renderButton()} {
this._renderSiftList()}
); }

_renderButton函数 负责按钮 showSiftList控制着是否显示SiftList

里面的item:

item:{
title:'交易方向', tag:0, list:[], }
_renderButton = ()=> {
const {
item,textStyle,style}=this.props; const {
showSiftList}=this.state; let icon = showSiftList?require('../images/icon_up.svg'):require('../images/btn_down.svg'); return (
{
item.title}
); };

_renderSiftList负责下拉菜单绘制,可以写成ListView,如果下拉菜单的高度不大,且确定就可以用ScrollView,这里就是用的ScrollView

_renderModal = ()=> {
const {
showSiftList,selectedIndex}=this.state; const {
style,item}=this.props; if (showSiftList && this._buttonFrame) {
let frameStyle = this._calculatePosition(); return (
{
item.list?item.list.map((sublist,i)=>{
return(
this.select(i)} key={
i} >
{ sublist}
) }):null}
); } };

计算SiftList菜单的位置

_calculatePosition = ()=> {
const {
style}=this.props; let dimensions = Dimensions.get('window'); let windowWidth = dimensions.width; let windowHeight = dimensions.height; let dropdownHeight = (style && StyleSheet.flatten(style).height) || StyleSheet.flatten(styles.dropdown).height; let bottomSpace = windowHeight - this._buttonFrame.y - this._buttonFrame.h; let rightSpace = windowWidth - this._buttonFrame.x; let showInBottom = bottomSpace >= dropdownHeight || bottomSpace >= this._buttonFrame.y; let showInLeft = rightSpace >= this._buttonFrame.x; var style = {
height: dropdownHeight, top: (showInBottom ? this._buttonFrame.y + this._buttonFrame.h : Math.max(0, this._buttonFrame.y - dropdownHeight))-0.5, } if (showInLeft) {
style.left = this._buttonFrame.x; } else {
let dropdownWidth = (style && StyleSheet.flatten(style).width) || -1; if (dropdownWidth !== -1) {
style.width = dropdownWidth; } style.right = rightSpace - this._buttonFrame.w; } if (this.props.adjustFrame) {
style = this.props.adjustFrame(style) || style; } return style; };

子项的选中和下拉菜单的显示、隐藏方法

show = ()=> {
this._updatePosition(() => {
this.setState({
showSiftList: true, }); }); }; hide = ()=> {
this.setState({
showSiftList: false, }); }; select = (index)=> {
const {
item,selectedCallBack}=this.props; const {
selectedIndex}=this.state; if (index == null || item.list == null || index >= item.list.length) {
index = selectedIndex; } this.setState({
selectedIndex: index, }); selectedCallBack&&selectedCallBack(index,item.tag); this.hide(); };

获取按钮对应位置的方法

_updatePosition = (callback)=>  {
if (this._button && this._button.measure) {
this._button.measure((fx, fy, width, height, px, py) => {
this._buttonFrame = {
x: px, y: py, w: width, h: height}; callback && callback(); }); } };

封装成一个组件SiftListControl

export default class SiftListControl extends Component {
static defaultProps = {
items:[ {
title:'交易方向', tag:0, icon:require('../images/btn_down.svg'), list:[], } ] }; constructor(){
super(); this.state = {
}; } _selectedIndex = (index,tag)=>{
const {
callBack}=this.props; callBack&&callBack(index,tag); }; render() {
const {
items,subItemStyle}=this.props; return (
{
items.map((item,i)=>{
return(
) }) }
); }}const styles = StyleSheet.create({
listBar:{
height:32, flexDirection:'row', }});

下载链接:


链接:http://www.imooc.com/article/15100

转载地址:http://mneni.baihongyu.com/

你可能感兴趣的文章
iOS分割线的操作方式
查看>>
iOS设置行高的多种方式以及优先级区分
查看>>
iOS数组排序
查看>>
CollectionView设置UICollectionReusableView头尾视图
查看>>
iOS图文混排
查看>>
iOS十六进制颜色转换成UIColor
查看>>
timer定时器
查看>>
清空导航控制器的黑线
查看>>
GCD单例-懒汉式&饿汉式
查看>>
GCD调度组实现原理
查看>>
GCD线程间通信
查看>>
GCD中的队列与任务组合对比
查看>>
GCD主队列死锁和全局队列
查看>>
NSBlockOperation线程间通信
查看>>
NSOperation的高级功能
查看>>
自定义NSOperation
查看>>
SDWebImage常用函数
查看>>
自动释放池和消息循环的关系
查看>>
ARC和MRC下Block的使用注意
查看>>
主线程和子线程中的消息循环
查看>>