React Native自定义控件底部抽屉菜单的示例


Posted in Javascript onFebruary 08, 2018

一、需求分析

原生开发中,自定义View可谓是屡见不鲜的事情,往往系统的控件总不能满足现实的需求。五花八门的产品设计需要我们做出不同的View。关于自定义View的内容网上已经有很多的博文,本篇博客要和大家分享如何在React Native中自定义组件实现抽屉菜单控件效果。分享功能在App中的重要性想必是不言而喻的,那么RN中如何实现这种效果呢?

React Native 系统库中只提供了IOS的实现,即ActionSheetIOS.该控件的显示方式有两种实现:

(1)showActionSheetWithOptions

(2)showShareActionSheetWithOptions

第一种是在iOS设备上显示一个ActionSheet弹出框。第二种实现是在iOS设备上显示一个分享弹出框。借用官方的图片说明如下:

React Native自定义控件底部抽屉菜单的示例  React Native自定义控件底部抽屉菜单的示例

IOS设备上的实现系统已经提供了,接下来我们就需要如何适配Android。在原生开发中,自定义View也是有基本的流程:

(1)自定义控件类,继承View或系统控件。

(2)自定义属性

(3)获取自定义属性,并初始化一系列工具类

(4)重写onMeasure方法,对控件进行测量

(5)如果是自定义布局,还需要重写onLayout进行布局

在React Native中自定义组件的思路基本和原生自定义相似。所以按照这个流程,我们一步步实现即可。

二、功能实现

1、自定义组件,实现Component

export default class AndroidActionSheet extends Component

2、自定义属性

// 1.声明所需要的属性 
static propTypes= { 
  title: React.PropTypes.string, // 标题 
  content: React.PropTypes.object, // 内容 
  show: React.PropTypes.func, // 显示 
  hide: React.PropTypes.func, // 隐藏 
}
constructor(props) { 
  super(props); 
  this.translateY = 150; 
  this.state = { 
    visible: false, 
    sheetAnim: new Animated.Value(this.translateY) 
  } 
  this.cancel = this.cancel.bind(this); 
}

3、实现基本布局

/** 
* Modal为最外层,ScrollView为内容层 
*/ 
render() { 
    const { visible, sheetAnim } = this.state; 
    return( 
      <Modal 
      visible={ visible } 
      transparent={ true } 
      animationType="none" 
      onRequestClose={ this.cancel } 
      > 
      <View style={ styles.wrapper }> 
              <TouchableOpacity style={styles.overlay} onPress={this.cancel}></TouchableOpacity> 
          <Animated.View 
            style={[styles.bd, {height: this.translateY, transform: [{translateY: sheetAnim}]}]}> 
            { this._renderTitle() } 
            <ScrollView 
                      horizontal={ true } 
                      showsHorizontalScrollIndicator={ false }> 
              {this._renderContainer()} 
            </ScrollView> 
          </Animated.View> 
        </View> 
      </Modal> 
    ) 
}

可以看到上面我们定义了基本的布局,布局中使用_renderTitle()方法来渲染标题部分,内容区域为ScrollView,并且为横向滚动,即当菜单项超过屏幕宽度时,可以横向滑动选择。在内部调用了renderContainer方法来渲染菜单:

/** 
* 标题 
*/ 
_renderTitle() { 
  const { title,titleStyle } = this.props; 
  if (!title) { 
    return null 
  } 
    // 确定传入的是不是一个React Element,防止渲染的时候出错 
  if (React.isValidElement(title)) { 
    return ( 
      <View style={styles.title}>{title}</View> 
    ) 
  } 
  return ( 
    <Text style={[styles.titleText,titleStyle]}>{title}</Text> 
  ) 
} 
 
/** 
* 内容布局 
*/ 
_renderContainer() { 
    const { content } = this.props; 
    return ( 
      <View style={styles.container}> 
        { content } 
      </View> 
    ) 
  }

当我们需要点击Modal,进行关闭时,还需要处理关闭操作,Modal并没有为我们提供外部关闭处理,所以需要我们单独实现,从布局代码中我们看到TouchableOpacity作为遮罩层,并添加了单机事件,调用cancel来处理:

/** 
 * 控制Modal点击关闭,Android返回键关闭 
 */ 
 cancel() { 
  this.hide(); 
}

4、自定义方法,对外调用

在外部我们需要控制控件的显示和隐藏,所以需要对外公开显示、关闭的方法:

/** 
 * 显示 
 */ 
show() { 
  this.setState({visible: true}) 
  Animated.timing(this.state.sheetAnim, { 
    toValue: 0, 
    duration: 250 
  }).start(); 
}
/** 
 * 隐藏 
 */ 
hide() { 
   this.setState({ visible: false }) 
   Animated.timing(this.state.sheetAnim, { 
    toValue: this.translateY, 
    duration: 150 
   }).start(); 
}

5、使用

<ActionSheet 
 ref='sheet' 
 title='分享' 
 content={this._renderContent()} 
/>

至此,我们自定义组件就完成了。整体来看,基本的原理还是很简单的,主要利用了自定义属性,传参,动画,就可以轻松的实现了。本篇博客重点不是为了让大家知道怎么去写出这个效果,而是让大家明白,当我们遇到一个需要自定义的实现时,该如何去一步步实现。

三、效果图

React Native自定义控件底部抽屉菜单的示例

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js修改table中Td的值(定义td的双击事件)
Jan 10 Javascript
js 自定义个性下拉选择框示例
Aug 20 Javascript
JQuery实现table行折叠效果以JSON做数据源
May 26 Javascript
jquery中cookie用法实例详解(获取,存储,删除等)
Jan 04 Javascript
javascript拖拽效果延伸学习
Apr 04 Javascript
js实现可控制左右方向的无缝滚动效果
May 29 Javascript
JavaScript中的Array 对象(数组对象)
Jun 02 Javascript
浅谈react性能优化的方法
Sep 05 Javascript
关于微信小程序登录的那些事
Jan 08 Javascript
vuex+axios+element-ui实现页面请求loading操作示例
Feb 02 Javascript
微信小程序通过websocket实时语音识别的实现代码
Aug 19 Javascript
vue自定义指令和动态路由实现权限控制
Aug 28 Javascript
vue 使用ref 让父组件调用子组件的方法
Feb 08 #Javascript
Vuejs 2.0 子组件访问/调用父组件的方法(示例代码)
Feb 08 #Javascript
web前端页面生成exe可执行文件的方法
Feb 08 #Javascript
ajax前台后台跨域请求处理方式
Feb 08 #Javascript
详解自定义ajax支持跨域组件封装
Feb 08 #Javascript
微信小程序实现验证码获取倒计时效果
Feb 08 #Javascript
ES6 迭代器(Iterator)和 for.of循环使用方法学习(总结)
Feb 08 #Javascript
You might like
什么是短波收听SWL
2021/03/01 无线电
php生成随机字符串可指定纯数字、纯字母或者混合的
2014/04/18 PHP
thinkPHP5框架闭包函数与子查询传参用法示例
2018/08/02 PHP
js获取和设置属性的方法
2014/02/20 Javascript
jquery1.10给新增元素绑定事件的方法
2014/03/06 Javascript
情人节单身的我是如何在敲完代码之后收到12束玫瑰的(javascript)
2015/08/21 Javascript
JavaScript基础篇(6)之函数表达式闭包
2015/12/11 Javascript
jQuery进行组件开发完整实例
2015/12/15 Javascript
极力推荐10个短小实用的JavaScript代码段
2016/08/03 Javascript
AngularJS自定义插件实现网站用户引导功能示例
2016/11/07 Javascript
BootStrap Validator 版本差异问题导致的submitHandler失效问题的解决方法
2016/12/01 Javascript
详解Angular系列之变化检测(Change Detection)
2018/02/26 Javascript
vue与vue-i18n结合实现后台数据的多语言切换方法
2018/03/08 Javascript
Vue官方推荐AJAX组件axios.js使用方法详解与API
2018/10/09 Javascript
VUE2.0 ElementUI2.0表格el-table自适应高度的实现方法
2018/11/28 Javascript
Layui带搜索的下拉框的使用以及动态数据绑定方法
2019/09/28 Javascript
Vue中通过属性绑定为元素绑定style行内样式的实例代码
2020/04/30 Javascript
基于Vue全局组件与局部组件的区别说明
2020/08/11 Javascript
解决Antd Table表头加Icon和气泡提示的坑
2020/11/17 Javascript
[00:43]DOTA2小紫本全民票选福利PA至宝全方位展示
2014/11/25 DOTA
从零学python系列之新版本导入httplib模块报ImportError解决方案
2014/05/23 Python
python with statement 进行文件操作指南
2014/08/22 Python
cmd运行python文件时对结果进行保存的方法
2018/05/16 Python
Python多进程fork()函数详解
2019/02/22 Python
django settings.py 配置文件及介绍
2019/07/15 Python
django 微信网页授权登陆的实现
2019/07/30 Python
python 数据生成excel导出(xlwt,wlsxwrite)代码实例
2019/08/23 Python
python中数字是否为可变类型
2020/07/08 Python
利用CSS3的border-radius绘制太极及爱心图案示例
2016/05/17 HTML / CSS
汤米巴哈马官方网站:Tommy Bahama
2017/05/13 全球购物
POP文化和音乐灵感的时尚:Hot Topic
2019/06/19 全球购物
Ibatis如何使用动态表名
2015/07/12 面试题
专升本个人自我评价
2013/12/22 职场文书
放假通知范文
2015/04/14 职场文书
不同品牌、不同型号对讲机如何互相通联
2022/02/18 无线电
Go中使用gjson来操作JSON数据的实现
2022/08/14 Golang