前言
本系列是基于React Native 版本号0.44.3 写的。很多的App 都使用了Tab 标签组件,例如QQ ,微信 等等,就是切换不同的选项,显示不同的内容。那么这篇文章将介绍RN 中的Tab 标签组件。
Tab 标签
什么是Tab 标签?(ps:我是这样叫的),就拿微信来说吧,底部有4个选项卡,点击不同的按钮切换不同的内容。 在RN 中有两个组件负责实现这样的效果,它们是:
TabBarIOS
和NavigatorIOS 相似,看名字就知道该组件只适用于iOS ,不能用于android 。
TabBarIOS 常用属性
barTintColor string:标签栏的背景颜色。
style:样式
tintColor string: 当前被选中的标签图标的颜色。 unselectedItemTintColor string: 当前没有被选中的标签图标的颜色。仅在iOS 10及以上版本有效
translucent bool: 一个布尔值,决定标签栏是否需要半透明化。
TabBarIOS.Item
- 注意:
TabBarIOS.Item 必须包装一个View ,作为点击选项卡,切换的view
TabBarIOS.Item 常用属性
badge string,number :在图标右上角显示一个红色的气泡。
icon Image.propTypes.source :给当前标签指定一个自定义的图标。如果定义了systemIcon属性, 这个属性会被忽略。
onPress function :当此标签被选中时调用。你应该修改组件的状态来使得selected={true}。
selected bool :这个属性决定了子视图是否可见。如果你看到一个空白的页面,很可能是没有选中任何一个标签。
selectedIcon Image.propTypes.source :当标签被选中的时候显示的自定义图标。如果定义了systemIcon属性,这个属性会被忽略。如果定义了icon而没定义这个属性,在选中的时候图标会染上蓝色。
systemIcon enum('bookmarks','contacts','downloads','favorites','featured','history','more','most-recent','most-viewed','recents','search','top-rated') :一些预定义的系统图标。注意如果你使用了此属性,标题和自定义图标都会被覆盖为系统定义的值。
title string :在图标下面显示的标题文字。如果定义了systemIcon属性,这个属性会被忽略
使用步骤
-
创建TabBar 标签: 使用下面行代码,底部就会有一个条 <TabBarIOS>
</TabBarIOS>
-
添加选项卡 <TabBarIOS.Item
title='首页'
icon={{uri: 'tabbar_home_select',scale: 3}}
>
<View style={{flex: 1,justifyContent: 'center',alignItems: 'center',backgroundColor: 'red'}}>
<Text>首页</Text>
</View>
</TabBarIOS.Item>
-
监听按钮点击,切换界面
- 只要设置对应的
tabBarItem 的selected 为true ,就会自动跳转到对应界面
- 注意:
tabBarItem 的selected 属性不能写死,可以定义个flag 来标记当前选中的item
- 监听
tabBarItem 的点击,修改selected 属性
实战演练
先看效果图:
我们在index.ios.js 文件做修改,直接创建一个TabBarIOS 组件:
render() {
return (
<TabBarIOS
tintColor='orange'
barTintColor='black'
>
</TabBarIOS>
);
}
再创建三个选项卡(ps:3个选项卡创建方式类似,所以这里只贴出创建一个的代码,),icon 是图片,关于图片方面的知识,本文最后做一个总结吧:
<TabBarIOS.Item
title='首页'
icon={{uri: 'tabbar_home_select',scale: 3}}
selected={true}
>
<View style={{flex: 1,backgroundColor: 'red'}}>
<Text>首页</Text>
</View>
</TabBarIOS.Item>
监听按钮点击,然后实现界面切换,我们需要定义一个flag 记录当前选中的,
constructor(props) {
super(props);
// 初始状态
this.state = {
selectIndex:0,};
}
给TabBarIOS.Item 添加点击事件:
<TabBarIOS.Item
title='首页'
icon={{uri: 'tabbar_home_select',scale: 3}}
onPress={()=>{
this.setState({
selectIndex:0
})
}}
selected={0==this.state.selectIndex}
>
我们会发现,创建3个TabBarIOS.Item 的代码是一样的,避免写重复代码,我们可以抽取出来:
_renderTabBarItem(title,iconName,selected,bgColor,badgeNumber){
return (
<TabBarIOS.Item
title={title}
icon={{uri: iconName,scale: 3}}
onPress={()=>{
this.setState({
selectIndex: selected
})
}}
badge={badgeNumber}
selected={this.state.selectIndex === selected}
>
<View style={{flex: 1,backgroundColor: bgColor}}>
<Text>{title}</Text>
</View>
</TabBarIOS.Item>
);
}
然后我们整个创建标签Tab 的代码就应该是这样:
render() {
return (
<TabBarIOS
tintColor='orange'
barTintColor='black'
>
{this._renderTabBarItem("首页",'tabbar_my_select','red',null)}
{this._renderTabBarItem("消息",1,'yellow',2)}
{this._renderTabBarItem("我的",2,'cyan',null)}
</TabBarIOS>
);
}
TabNavigator
本系列上篇文章中,介绍到React Navigation 组件中包含了TabNavigator 。所以接下来的讲解是在引入了React Navigation 的基础之上的。
常用属性
screen:和导航的功能是一样的,对应界面名称,可以在其他页面通过这个screen传值和跳转。
navigationOptions:配置TabNavigator的一些属性
{
title:标题,会同时设置导航条和标签栏的title
tabBarVisible:是否隐藏标签栏。默认不隐藏(true)
tabBarIcon:设置标签栏的图标。需要给每个都设置
tabBarLabel:设置标签栏的title。推荐
}
tabBarPosition:设置tabbar的位置,iOS默认在底部,安卓默认在顶部。(属性值:'top','bottom')
swipeEnabled:是否允许在标签之间进行滑动
animationEnabled:是否在更改标签时显示动画
lazy:是否根据需要懒惰呈现标签,而不是提前,意思是在app打开的时候将底部标签栏全部加载,默认false,推荐为true
trueinitialRouteName: 设置默认的页面组件
backBehavior:按 back 键是否跳转到第一个Tab(首页), none 为不跳转
tabBarOptions:配置标签栏的一些属性iOS属性
activeTintColor:label和icon的前景色 活跃状态下
activeBackgroundColor:label和icon的背景色 活跃状态下
inactiveTintColor:label和icon的前景色 不活跃状态下
inactiveBackgroundColor:label和icon的背景色 不活跃状态下
showLabel:是否显示label,默认开启 style:tabbar的样式
labelStyle:label的样式安卓属性
activeTintColor:label和icon的前景色 活跃状态下
inactiveTintColor:label和icon的前景色 不活跃状态下
showIcon:是否显示图标,默认关闭
showLabel:是否显示label,默认开启 style:tabbar的样式
labelStyle:label的样式 upperCaseLabel:是否使标签大写,默认为true
pressColor:material涟漪效果的颜色(安卓版本需要大于5.0)
pressOpacity:按压标签的透明度变化(安卓版本需要小于5.0)
scrollEnabled:是否启用可滚动选项卡 tabStyle:tab的样式
indicatorStyle:标签指示器的样式对象(选项卡底部的行)。安卓底部会多出一条线,可以将height设置为0来暂时解决这个问题
labelStyle:label的样式
iconStyle:图标样式
实战演练
我们创建App.js ,然后在index.ios.js 文件引用该组件:
import App from './App'
export default class RNDemoTwo extends Component {
render() {
return (
<App/>
);
}
}
现在来配置下App.js 文件:
import {TabNavigator} from 'react-navigation'
import HelloViewCompnent from './HelloViewComponent'
import DetailComponent from './DetailComponent'
import ThreeComponent from './Three'
import CustTabBarItem from "./TabBarItem"
const SimpleApp = TabNavigator({
Home: {
screen: HelloViewCompnent,navigationOptions: ({navigation}) => ({
tabBarVisible: true,tabBarLabel: '首页',tabBarIcon: ({focused,tintColor})=>(
<CustTabBarItem
tintColor={tintColor}
focused={focused}
selectImage={{uri: 'tabbar_home_select'}}
normalImage={{uri: 'tabbar_home'}}
/>
),})
},Detail: {
screen: DetailComponent,navigationOptions: ({navigation}) => ({
tabBarLabel: '消息',tintColor})=>(
<CustTabBarItem
tintColor={tintColor}
focused={focused}
selectImage={{uri: 'tabbar_licai_select'}}
normalImage={{uri: 'tabbar_licai'}}
/>
),Three: {
screen: ThreeComponent,navigationOptions: ({navigation}) => ({
tabBarLabel: '我的',tintColor})=>(
<CustTabBarItem
tintColor={tintColor}
focused={focused}
selectImage={{uri: 'tabbar_my_select'}}
normalImage={{uri: 'tabbar_my'}}
/>
),})
}
},{
tabBarPosition:'bottom',swipeEnabled:false,animationEnabled:false,lazy:true,tabBarOptions:{
activeTintColor:'red',inactiveTintColor:'black',style:{backgroundColor:'#fff',},labelStyle: {
fontSize: 16,// 文字大小
},}
})
export default SimpleApp
可以看到我们导入了三个页面组件,一个CustTabBarItem , 三个页面组件很简单,都类似,由于篇幅原因,只贴出一个就行了:
export default class HelloViewCompnent extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
首页
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,backgroundColor: 'white',welcome: {
fontSize: 20,textAlign: 'center',margin: 10,});
最后,就是我们的TabBarItem.js 文件了:
export default class TabBarItem extends Component {
render(){
return (
<Image source={this.props.focused ? this.props.selectImage : this.props.normalImage}
style={{tintColor: this.props.tintColor,width: 25,height: 25}}/>
);
}
}
保存代码,运行项目,不出意外,应该和使用TabBarIOS 是一样的效果。
关于Image组件
由于这里我们都使用到<Image/> 组件,这里就稍微讲一下。
- Image:用于加载图片,可加载网络图片,也可以加载本地图片
-
Image常用属性 source {uri: string},number : 设置Image图片资源
blurRadius number:让图片模糊
defaultSource {uri: string,width: number,height:number,scale: number},number 占位图片,在读取图片时默认显示的加载提示图片
resizeMode enum('cover','contain','stretch','repeat','center') 决定图片尺寸大小。
cover: 在保持图片宽高比的前提下缩放图片,直到宽度和高度都大于等于容器视图的尺寸(如果容器有padding内衬的话,则相应减去)。译注:这样图片完全覆盖甚至超出容器,容器中不留任何空白。
contain: 在保持图片宽高比的前提下缩放图片,直到宽度和高度都小于等于容器视图的尺寸(如果容器有padding内衬的话,则相应减去)。译注:这样图片完全被包裹在容器中,容器中可能留有空白
stretch: 拉伸图片且不维持宽高比,直到宽高都刚好填满容器。
repeat: 重复平铺图片直到填满容器。图片会维持原始尺寸。仅iOS可用。
center: 居中不拉伸。
-
本地图片存放位置
-
- 直接放在RN项目中
-
- 可以放在
ios 项目中,放到images.xcassets 文件中
-
- 可以放在
android 项目中(安卓中图片文字不能以数字开头,也不能有大写字母)
-
如何加载本地图片
- RN中加载资源:require(文件路径),用于加载RN中的资源,不管是图片,还是json都是一样的
- uri:指定一个资源路径,就会自动加载
- uri加载注意:通过uri加载资源,必须设置图片尺寸,否则不显示
- 如果网络加载http图片,iOS默认不支持,需要开启
App Transport 。
致谢
如果发现有错误的地方,欢迎各位指出,谢谢! (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|