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 相关文章推荐
许愿墙中用到的函数
Oct 07 Javascript
JavaScript DOM学习第六章 表单实例
Feb 19 Javascript
JQuyer $.post 与 $.ajax 访问WCF ajax service 时的问题需要注意的地方
Sep 20 Javascript
一个JQuery操作Table的代码分享
Mar 30 Javascript
Lazy Load 延迟加载图片的jQuery插件中文使用文档
Oct 18 Javascript
JSON语法五大要素图文介绍
Dec 04 Javascript
弹出最简单的模式化遮罩层的js代码
Dec 04 Javascript
jQuery中data()方法用法实例
Dec 27 Javascript
用js实现简单算法的实例代码
Sep 24 Javascript
Angularjs 创建可复用组件实例代码
Oct 09 Javascript
说说如何利用 Node.js 代理解决跨域问题
Apr 22 Javascript
Vue利用localStorage本地缓存使页面刷新验证码不清零功能的实现
Sep 04 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
PHP使用递归生成文章树
2015/04/21 PHP
浅析PHP中的 inet_pton 网络函数
2019/12/16 PHP
Prototype使用指南之range.js
2007/01/10 Javascript
JS 时间显示效果代码
2009/08/23 Javascript
一个分享按钮的插件使用介绍(可扩展,内附开发制作流程)
2011/09/19 Javascript
js实现点击后将文字或图片复制到剪贴板的方法
2014/08/04 Javascript
浅谈javascript中的DOM方法
2015/07/16 Javascript
JavaScript前端开发之实现二进制读写操作
2015/11/04 Javascript
EasyUI中在表单提交之前进行验证
2016/07/19 Javascript
原生Javascript插件开发实践
2017/01/18 Javascript
JavaScript数组迭代方法
2017/03/03 Javascript
AngularJS折叠菜单实现方法示例
2017/05/18 Javascript
将 vue 生成的 js 上传到七牛的实例
2017/07/28 Javascript
详解React之key的使用和实践
2018/09/29 Javascript
浅谈目前可以使用ES10的5个新特性
2019/06/25 Javascript
用Golang运行JavaScript的实现示例
2019/11/25 Javascript
JS中间件设计模式的深入探讨与实例分析
2020/04/11 Javascript
你不知道的 TypeScript 高级类型(小结)
2020/08/28 Javascript
Vue项目打包部署到apache服务器的方法步骤
2021/02/01 Vue.js
[02:05]DOTA2完美大师赛趣味视频之看我表演
2017/11/18 DOTA
在Python web中实现验证码图片代码分享
2017/11/09 Python
详解Python中的Numpy、SciPy、MatPlotLib安装与配置
2017/11/17 Python
python生成圆形图片的方法
2020/03/25 Python
Python变量访问权限控制详解
2019/06/29 Python
python config文件的读写操作示例
2019/09/27 Python
python框架flask入门之路由及简单实现方法
2020/06/07 Python
python中如何写类
2020/06/29 Python
Python使用Selenium模拟浏览器自动操作功能
2020/09/08 Python
Python 利用flask搭建一个共享服务器的步骤
2020/12/05 Python
使用phonegap操作数据库的实现方法
2017/03/31 HTML / CSS
党员学习十八大感想
2014/01/17 职场文书
大学自我评价
2014/02/12 职场文书
债务追讨授权委托书范本
2014/10/16 职场文书
2015应届毕业生自荐信范文
2015/03/05 职场文书
年会主持人开场白台词
2015/05/29 职场文书
励志语录:时光飞逝,请学会珍惜所有的人和事
2020/01/16 职场文书