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 相关文章推荐
javascript 打印内容方法小结
Nov 04 Javascript
JavaScript中使用正则匹配多条,且获取每条中的分组数据
Nov 30 Javascript
使用JS CSS去除IE链接虚线框的三种方法
Nov 14 Javascript
JavaScript监听文本框回车事件并过滤文本框空格的方法
Apr 16 Javascript
纯js实现重发验证码按钮倒数功能
Apr 21 Javascript
深入理解Angular2 模板语法
Aug 07 Javascript
利用fecha进行JS日期处理
Nov 21 Javascript
jQuery插件jquery.kxbdmarquee.js实现无缝滚动效果
Feb 15 Javascript
javascript实现数据双向绑定的三种方式小结
Mar 09 Javascript
使用 Node.js 对文本内容分词和关键词抽取
May 27 Javascript
JavaScript深拷贝和浅拷贝概念与用法实例分析
Jun 07 Javascript
Vue核心概念Getter的使用方法
Jan 18 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
批量获取memcache值并按key的顺序返回的实现代码
2011/06/14 PHP
PHP生成数组再传给js的方法
2014/08/07 PHP
php结合md5实现的加密解密方法
2016/01/25 PHP
PHP页面输出时js设置input框的选中值
2016/09/30 PHP
Zend Framework使用Zend_Loader组件动态加载文件和类用法详解
2016/12/09 PHP
php常用的工具开发整理
2019/09/26 PHP
JavaScript效率调优经验
2009/06/04 Javascript
javascript显示用户停留时间的简单实例
2013/08/05 Javascript
js中Image对象以及对其预加载处理示例
2013/11/20 Javascript
Angularjs中$http以post请求通过消息体传递参数的实现方法
2016/08/05 Javascript
Nodejs进阶:核心模块net入门学习与实例讲解
2016/11/21 NodeJs
无阻塞加载js,防止因js加载不了影响页面显示的问题
2016/12/18 Javascript
JS去除字符串中空格的方法
2017/02/14 Javascript
NodeJs实现定时任务的示例代码
2017/12/05 NodeJs
微信小程序学习笔记之登录API与获取用户信息操作图文详解
2019/03/29 Javascript
用pywin32实现windows模拟鼠标及键盘动作
2014/04/22 Python
Python自动化开发学习之三级菜单制作
2017/07/14 Python
Python实现将json文件中向量写入Excel的方法
2018/03/26 Python
浅析python中的迭代与迭代对象
2018/10/08 Python
python实现一组典型数据格式转换
2018/12/15 Python
python图形工具turtle绘制国际象棋棋盘
2019/05/23 Python
python 调用pyautogui 实时获取鼠标的位置、移动鼠标的方法
2019/08/27 Python
tensorflow 模型权重导出实例
2020/01/24 Python
Python列表list操作相关知识小结
2020/01/29 Python
windows+vscode安装paddleOCR运行环境的步骤
2020/11/11 Python
运动鞋、足球鞋和慕尼黑球衣:Sport Münzinger
2019/08/26 全球购物
英国现代家具和照明购物网站:Heal’s
2019/10/30 全球购物
高分子材料个人求职信范文
2013/09/25 职场文书
法学研究生自我鉴定范文
2013/12/04 职场文书
思想政治教育专业个人求职信范文
2013/12/20 职场文书
高三政治教学反思
2014/02/06 职场文书
社区挂职锻炼个人工作总结
2015/10/23 职场文书
幼儿园家长心得体会
2016/01/21 职场文书
如何起草一份正确的合伙创业协议书?
2019/07/04 职场文书
MYSQL事务的隔离级别与MVCC
2022/05/25 MySQL
Nginx代理Redis哨兵主从配置的实现
2022/07/15 Servers