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写的日历(代码部分网摘)
Sep 20 Javascript
jquery中邮箱地址 URL网站地址正则验证实例代码
Sep 15 Javascript
Jquery 获取对象的几种方式介绍
Jan 17 Javascript
jquery实现选中单选按钮下拉伸缩效果
Aug 06 Javascript
window.open打开窗口被拦截的快速解决方法
Aug 04 Javascript
html5+CSS 实现禁止IOS长按复制粘贴功能
Dec 28 Javascript
Bootstrap模态框(Modal)实现过渡效果
Mar 17 Javascript
Bootstrap table学习笔记(2) 前后端分页模糊查询
May 18 Javascript
bootstrap multiselect 多选功能实现方法
Jun 05 Javascript
Vue+element 解决浏览器自动填充记住的账号密码问题
Jun 11 Javascript
vue 父组件通过v-model接收子组件的值的代码
Oct 27 Javascript
javascript实现页面的实时时钟显示示例
Aug 06 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制作中间带自己定义图片二维码的方法
2014/01/27 PHP
PHP针对多用户实现更换头像功能
2016/09/04 PHP
php微信公众号开发模式详解
2016/11/28 PHP
PHP队列场景以及实现代码实例详解
2021/02/26 PHP
JavaScript 设计模式学习 Factory
2009/07/29 Javascript
收集的一些Array及String原型对象的扩展实现代码
2010/12/05 Javascript
js如何获取兄弟、父类等节点
2014/01/06 Javascript
详解JavaScript中循环控制语句的用法
2015/06/03 Javascript
javascript 闭包详解
2015/07/02 Javascript
详解javascript数组去重问题
2015/11/06 Javascript
BootStrap制作导航条实例代码
2016/05/06 Javascript
JS获取当前页面名称的简单实例
2016/08/19 Javascript
Bootstrap CSS组件之分页(pagination)和翻页(pager)
2016/12/17 Javascript
AngularJS表单基本操作
2017/01/09 Javascript
vue组件父子间通信之综合练习(聊天室)
2017/11/07 Javascript
React diff算法的实现示例
2018/04/20 Javascript
详解如何模拟实现node中的Events模块(通俗易懂版)
2019/04/15 Javascript
js实现无缝轮播图效果
2020/03/09 Javascript
前端开发基础javaScript的六大作用
2020/08/06 Javascript
使用python3.5仿微软记事本notepad
2016/06/15 Python
浅谈Python 字符串格式化输出(format/printf)
2016/07/21 Python
Python实现手写一个类似django的web框架示例
2018/07/20 Python
Flask使用Pyecharts在单个页面展示多个图表的方法
2019/08/05 Python
python列表生成器迭代器实例解析
2019/12/19 Python
PyQt5.6+pycharm配置以及pyinstaller生成exe(小白教程)
2020/06/02 Python
python如何爬取网页中的文字
2020/07/28 Python
Python抓包并解析json爬虫的完整实例代码
2020/11/03 Python
GetYourGuide台湾:预订旅游活动、景点和旅游项目
2019/06/10 全球购物
Sunglass Hut巴西网上商店:男女太阳镜
2020/10/04 全球购物
诺思信科技(南京)有限公司.NET笔试题答案
2013/07/06 面试题
2014的自我评价
2014/01/13 职场文书
服务质量承诺书
2014/03/27 职场文书
2014年项目工作总结
2014/11/24 职场文书
公司2014年度工作总结
2014/12/10 职场文书
2015年业务员工作总结范文
2015/04/07 职场文书
SQL实现LeetCode(180.连续的数字)
2021/08/04 MySQL