搜索
您的当前位置:首页正文

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

2023-12-08 来源:爱乐情感

一、需求分析

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

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

(1)showActionSheetWithOptions

(2)showShareActionSheetWithOptions

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

  

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()} /> 

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

三、效果图

小编还为您整理了以下内容,可能对您也有帮助:

使用ReactNative如何实现自定义控件底部抽屉菜单

本篇文章主要介绍了React Native自定义控件底部抽屉菜单的示例,现在分享给大家,也给大家做个参考。

一、需求分析

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

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

(1)showActionSheetWithOptions

(2)showShareActionSheetWithOptions

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

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

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

(2)自定义属性

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

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

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

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

二、功能实现

1、自定义组件,实现Component

export default class AndroidActionSheet extends Component2、自定义属性

// 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,

ration: 250

}).start();

}/**

* 隐藏

*/

hide() {

this.setState({ visible: false })

Animated.timing(this.state.sheetAnim, {

toValue: this.translateY,

ration: 150

}).start();

}5、使用

<ActionSheet

ref='sheet'

title='分享'

content={this._renderContent()}

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

三、效果图

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在mint-ui中使用时间插件及获取选择值

VUE2实现二级省市联动选择

使用react实现分页组件

ReactNative之Flex布局

一般使用ReactNative开发App,一般都采用Flex布局,使用这套布局就非常快。
Flex简介
Flex又叫弹性布局,会把当前组件看做一个容器,他的所有子组件都是他容器中的成员,通过Flex,就能迅速的布局容器中的成员。
使用场景:当想快速布局一个组件中所有子组件的时候,可以使用Flex布局

Flex主轴和侧轴
Flex中有两个主要的概念:主轴和侧轴
主轴与侧轴的关系:相互垂直的。
主轴:决定容器中子组件默认的布局方向:水平,垂直
侧轴:决定容器中子组件与主轴垂直的布局方向比如主轴水平,那么子组件默认就是水平布局排布,侧轴就是控制子组件在垂直方向的布局

flexDirection属性
flexDirection:决定主轴的方向,水平或者垂直,这样子组件就会水平排布或者垂直排布
flexDirection共有四个值,在RN中默认为column。

row(默认值):主轴为水平方向,从左向右。依次排列row-reverse:主轴为水平方向,从右向左依次排列column:主轴为垂直方向,默认的排列方式,从上向下排列column-reverse:主轴为垂直方向,从下向上排列

使用:

效果
row

row.png

row-reverse

row-reverse.png

column

column.png

column-reverse

column-reverse .png

flexWrap属性
flexWrap:决定子控件在父视图内是否允许多行排列。
flexWrap共有两个值,默认为nowrap。

nowrap 组件只排列在一行上,可能导致溢出。wrap 组件在一行排列不下时,就进行多行排列

使用

效果
nowrap

nowrap.png

wrap

wrap.png

justifyContent
justifyContent:决定子组件在主轴中具体布局,是靠左,还是居中等
justifyContent共有五个值,默认为flex-start

flex-start: 子组件向主轴起点对齐,如果主轴水平,从左开始,主轴垂直,从上开始。flex-end 子组件向主轴终点对齐,如果主轴水平,从右开始,主轴垂直,从下开始。center 居中显示,注意:并不是让某一个子组件居中,而是整体有居中效果space-between 均匀分配,相邻元素间距离相同。每行第一个组件与行首对齐,每行最后一个组件与行尾对齐。space-around 均匀分配,相邻元素间距离相同。每行第一个组件到行首的距离和每行最后一个组件到行尾的距离将会是相邻元素之间距离的一半

使用

效果
flex-start

flex-start.png

flex-end

flex-end.png

center

center.png

space-between

space-between .png

space-around

space-around.png

alignItems
alignItems:决定子组件在测轴中具体布局一直都没有管过侧轴,如果侧轴垂直,决定子组件在上,还是下,或者居中

alignItems共有四个值,默认为stretch。

flex-start 子组件向侧轴起点对齐。flex-end 子组件向侧轴终点对齐。center 子组件在侧轴居中。stretch 子组件在侧轴方向被拉伸到与容器相同的高度或宽度。

使用

效果
flex-start

flex-start .png

flex-end

flex-end .png

center

center .png

stretch

stretch .png

alignSelf
alignSelf:自定义自己的侧轴布局,用于一个子组件设置。注意:当某个子组件不想参照默认的alignItems时,可以设置alignSelf,自定义自己的侧轴布局。

alignSelf共有五个值,默认为auto。

auto 继承它的父容器的alignItems属性。如果没有父容器则为 "stretch"flex-start 子组件向侧轴起点对齐。flex-end 子组件向侧轴终点对齐。center 子组件在侧轴居中。stretch 子组件在侧轴方向被拉伸到与容器相同的高度或宽度。

使用

效果

alignSelf.png

flex
flex: 决定子控件在主轴中占据几等分。
flex: 任意数字,所有子控件flex相加,自己flex占总共多少,就有多少宽度.

使用

export default class ReactDemo extends Component { render() { return ( <View style={styles.rootView}> <Text style={[styles.text1Style,styles.baseTextStyle]}>1</Text> <Text style={[styles.text2Style,styles.baseTextStyle]}>2</Text> <Text style={[styles.text3Style,styles.baseTextStyle]}>3</Text> <Text style={[styles.text4Style,styles.baseTextStyle]}>4</Text> </View> ); }}const styles = StyleSheet.create({ rootView:{ backgroundColor:'darkorange', flex:1, flexDirection:'row', justifyContent:'space-around', alignItems:'center' }, baseTextStyle:{ // width:50, // height:50, fontSize:15, textAlign:'center', marginTop:20, }, text1Style:{ flex:1, backgroundColor:'red', }, text2Style:{ flex:1, backgroundColor:'deepskyblue', }, text3Style:{ flex:3, backgroundColor:'green' }, text4Style:{ flex:1, backgroundColor:'blue', }});

效果

flex.png

ReactNative之Flex布局

一般使用ReactNative开发App,一般都采用Flex布局,使用这套布局就非常快。
Flex简介
Flex又叫弹性布局,会把当前组件看做一个容器,他的所有子组件都是他容器中的成员,通过Flex,就能迅速的布局容器中的成员。
使用场景:当想快速布局一个组件中所有子组件的时候,可以使用Flex布局

Flex主轴和侧轴
Flex中有两个主要的概念:主轴和侧轴
主轴与侧轴的关系:相互垂直的。
主轴:决定容器中子组件默认的布局方向:水平,垂直
侧轴:决定容器中子组件与主轴垂直的布局方向比如主轴水平,那么子组件默认就是水平布局排布,侧轴就是控制子组件在垂直方向的布局

flexDirection属性
flexDirection:决定主轴的方向,水平或者垂直,这样子组件就会水平排布或者垂直排布
flexDirection共有四个值,在RN中默认为column。

row(默认值):主轴为水平方向,从左向右。依次排列row-reverse:主轴为水平方向,从右向左依次排列column:主轴为垂直方向,默认的排列方式,从上向下排列column-reverse:主轴为垂直方向,从下向上排列

使用:

效果
row

row.png

row-reverse

row-reverse.png

column

column.png

column-reverse

column-reverse .png

flexWrap属性
flexWrap:决定子控件在父视图内是否允许多行排列。
flexWrap共有两个值,默认为nowrap。

nowrap 组件只排列在一行上,可能导致溢出。wrap 组件在一行排列不下时,就进行多行排列

使用

效果
nowrap

nowrap.png

wrap

wrap.png

justifyContent
justifyContent:决定子组件在主轴中具体布局,是靠左,还是居中等
justifyContent共有五个值,默认为flex-start

flex-start: 子组件向主轴起点对齐,如果主轴水平,从左开始,主轴垂直,从上开始。flex-end 子组件向主轴终点对齐,如果主轴水平,从右开始,主轴垂直,从下开始。center 居中显示,注意:并不是让某一个子组件居中,而是整体有居中效果space-between 均匀分配,相邻元素间距离相同。每行第一个组件与行首对齐,每行最后一个组件与行尾对齐。space-around 均匀分配,相邻元素间距离相同。每行第一个组件到行首的距离和每行最后一个组件到行尾的距离将会是相邻元素之间距离的一半

使用

效果
flex-start

flex-start.png

flex-end

flex-end.png

center

center.png

space-between

space-between .png

space-around

space-around.png

alignItems
alignItems:决定子组件在测轴中具体布局一直都没有管过侧轴,如果侧轴垂直,决定子组件在上,还是下,或者居中

alignItems共有四个值,默认为stretch。

flex-start 子组件向侧轴起点对齐。flex-end 子组件向侧轴终点对齐。center 子组件在侧轴居中。stretch 子组件在侧轴方向被拉伸到与容器相同的高度或宽度。

使用

效果
flex-start

flex-start .png

flex-end

flex-end .png

center

center .png

stretch

stretch .png

alignSelf
alignSelf:自定义自己的侧轴布局,用于一个子组件设置。注意:当某个子组件不想参照默认的alignItems时,可以设置alignSelf,自定义自己的侧轴布局。

alignSelf共有五个值,默认为auto。

auto 继承它的父容器的alignItems属性。如果没有父容器则为 "stretch"flex-start 子组件向侧轴起点对齐。flex-end 子组件向侧轴终点对齐。center 子组件在侧轴居中。stretch 子组件在侧轴方向被拉伸到与容器相同的高度或宽度。

使用

效果

alignSelf.png

flex
flex: 决定子控件在主轴中占据几等分。
flex: 任意数字,所有子控件flex相加,自己flex占总共多少,就有多少宽度.

使用

export default class ReactDemo extends Component { render() { return ( <View style={styles.rootView}> <Text style={[styles.text1Style,styles.baseTextStyle]}>1</Text> <Text style={[styles.text2Style,styles.baseTextStyle]}>2</Text> <Text style={[styles.text3Style,styles.baseTextStyle]}>3</Text> <Text style={[styles.text4Style,styles.baseTextStyle]}>4</Text> </View> ); }}const styles = StyleSheet.create({ rootView:{ backgroundColor:'darkorange', flex:1, flexDirection:'row', justifyContent:'space-around', alignItems:'center' }, baseTextStyle:{ // width:50, // height:50, fontSize:15, textAlign:'center', marginTop:20, }, text1Style:{ flex:1, backgroundColor:'red', }, text2Style:{ flex:1, backgroundColor:'deepskyblue', }, text3Style:{ flex:3, backgroundColor:'green' }, text4Style:{ flex:1, backgroundColor:'blue', }});

效果

flex.png

React Native封装iOS自定义原生组件

简单描述下RN如何封装iOS自定义原生组件,做了一个简单的demo,封装一个DatePicker控件,控件中有取消和确定两个按钮。取消和确定两个按钮的点击事件与RN进行交互,将选择的时间传递给RN。

以下是具体的实现方式:

一、创建继承自UIView的DataPickerView,定义监听取消、确定按钮点击事件的delegate,暴露给JS的RCTBubblingEventBlock,将按钮点击事件与数据通过block方式回调给JS

二、将取消、确定点击事件传递给Delegate

三、创建继承自RCTViewManager的DatePickerViewManager,定义DataPickerView属性

四、DatePickerViewManager中将视图模块、事件回调暴露给JS,重写view方法

五、RN端通过requireNativeComponent来引入自定义原生组件

六、在需要使用该原生组件时引入CustomDatePicker这个组件即可

注:1、RN读取原生控件的回调数据,使用e.nativeEvent读取。

2、如果原生控件需要通过RN端的传递的属性来配置页面或其他的操作,则在自定义view中定义属性的时候需要重写setXxx:方法,在方法中来处理ui上的显示。

如:自定义控件需要显示RN传递的string

(1)自定义view中定义@property (nonatomic, copy) NSString *title;

(2)view.m中重写setTitle方法

- (void)setTitle:(NSString*)title {

    _titleLabel.text= title;

    }

(3)viewmanager中导出属性RCT_EXPORT_VIEW_PROPERTY(title, NSString)

(4)RN中初始化组件时传递属性

React Native设置背景透明,文字不透明的控件

在用RN写页面UI的时候,需要个背景透明文字不透明的 登录/注册控件,如下图

这是它的节点结构:

节点的style:

login:{

    zIndex:999,

    width:70,

    height:24,

    position:'absolute',

    right:15,

    top:30,

    backgroundColor:'rgba(178,178,178,0.5)',

    borderRadius:3,

    justifyContent: 'center',

  },

  loginText:{

    fontSize:14,

    color:'white',

    height:24,

    textAlign:'center',

    lineHeight:24,

    opacity:1.0

  },

设置如上控件的要点:必须设置父节点的 backgroundColor:'rgba(178,178,178,0.5)',必须使用rgba设置颜色样式

不能用16进制的颜色设置,否则会使得文字也改变了透明度

爱乐情感还为您提供以下相关内容希望对您有帮助:

使用ReactNative如何实现自定义控件底部抽屉菜单

(2)自定义属性(3)获取自定义属性,并初始化一系列工具类(4)重写onMeasure方法,对控件进行测量(5)如果是自定义布局,还需要重写onLayout进行布局在React Native中自定义组件的思路基本和原生自定义相似。所以按照这个流...

本文如未解决您的问题请添加抖音号:51dongshi(抖音搜索懂视),直接咨询即可。

Top