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 相关文章推荐
在jQuery 1.5中使用deferred对象的代码(翻译)
Mar 10 Javascript
JavaScript实现图片DIV竖向滑动的方法
Apr 25 Javascript
jQuery构造函数init参数分析续
May 13 Javascript
jQuery实现的Div窗口震动效果实例
Aug 07 Javascript
jquery对象和DOM对象的任意相互转换
Feb 21 Javascript
js 能实现监听F5页面刷新子iframe 而父页面不刷新的方法
Nov 09 Javascript
详解MVC如何使用开源分页插件(shenniu.pager.js)
Dec 16 Javascript
bootstrap警告框示例代码分享
May 17 Javascript
Vue.js实现输入框绑定的实例代码
Aug 24 Javascript
react-router 路由切换动画的实现示例
Dec 03 Javascript
Node.js 实现抢票小工具 &amp; 短信通知提醒功能
Oct 22 Javascript
原生JavaScript实现的无缝滚动功能详解
Jan 17 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脚本数据库功能详解(中)
2006/10/09 PHP
php生成WAP页面
2006/10/09 PHP
PHP中数组合并的两种方法及区别介绍
2012/09/14 PHP
php面向对象中static静态属性与方法的内存位置分析
2015/02/08 PHP
PHP实现基于mysqli的Model基类完整实例
2016/04/08 PHP
php实现的pdo公共类定义与用法示例
2017/07/19 PHP
Referer原理与图片防盗链实现方法详解
2019/07/03 PHP
jQuery EasyUI 的EasyLoader功能介绍
2010/09/12 Javascript
jQuery客户端分页实例代码
2013/11/18 Javascript
JS去掉第一个字符和最后一个字符的实现代码
2014/02/20 Javascript
基于jQuery实现放大镜特效
2020/10/19 Javascript
jQuery EasyUI右键菜单实现关闭标签/选项卡
2016/10/10 Javascript
详解js的六大数据类型
2016/12/27 Javascript
xmlplus组件设计系列之图标(ICON)(1)
2017/05/05 Javascript
Angular4学习教程之HTML属性绑定的方法
2018/01/04 Javascript
微信小程序调用天气接口并且渲染在页面过程详解
2019/06/24 Javascript
小程序实现短信登录倒计时
2019/07/12 Javascript
layui2.0使用table+laypage实现真分页
2019/07/27 Javascript
基于iview-admin实现动态路由的示例代码
2019/10/02 Javascript
JavaScript或jQuery 获取option value值方法解析
2020/05/12 jQuery
Vue 列表页带参数进详情页的操作(router-link)
2020/11/13 Javascript
Python中列表(list)操作方法汇总
2014/08/18 Python
pygame学习笔记(3):运动速率、时间、事件、文字
2015/04/15 Python
介绍Python中内置的itertools模块
2015/04/29 Python
Python实现删除当前目录下除当前脚本以外的文件和文件夹实例
2015/07/27 Python
深入理解Python变量与常量
2016/06/02 Python
Python的Flask框架中的Jinja2模板引擎学习教程
2016/06/30 Python
利用Python获取操作系统信息实例
2016/09/02 Python
解决python3中自定义wsgi函数,make_server函数报错的问题
2017/11/21 Python
查看django版本的方法分享
2018/05/14 Python
pytorch实现mnist分类的示例讲解
2020/01/10 Python
python用Tkinter做自己的中文代码编辑器
2020/09/07 Python
Html5之title吸顶功能
2018/06/04 HTML / CSS
试述DBMS的主要功能
2016/11/13 面试题
个人务虚会发言材料
2014/10/20 职场文书
Django数据库(SQlite)基本入门使用教程
2022/07/07 Python