React Native 带你一步一步实现TabNavitator前面我们已经大体实现了TabNavitator,下面我们接着前面的内容继续往下走哈,我们上一节写到了TabNavitator的render方法了:
render() {
//获取相应的props内容
let{style,children,sceneStyle,...props}=this.props;
//遍历所有的children
//需要显示的页面跟显示过的页面
let scenes=[];
React.Children.forEach(children,(child,index)=>{
if(child===null){
return;
}
//根据子view获取唯一key
let key=this._getSceneKey(child,index);
let {renderedSceneKeys}=this.state;
//判断该view是不是将要显示的view或者是不是显示过的view
if(!renderedSceneKeys.has(key)){
return;
}
//当前view为选中状态就设置其样式为sceneContainer
let scene=null;
if (child.props.selected) {
scene = (
<View {...child.props} style={styles.sceneContainer} pointerEvents={'auto'} removeClippedSubviews={false}>
{child}
</View>
)
} else {//当前view为未选中状态就设置其样式为hiddenSceneContainer
scene = (
<View {...child.props}style={styles.hiddenSceneContainer} pointerEvents={'none'} removeClippedSubviews={false}>
{child}
</View>
)
}
if(scene!==null)scenes.push(scene);
});
//选出当前需要显示的view
let currScene = null;
scenes.forEach((page, index)=> {
if (page.props.selected) {
currScene = page;
return;
}
});
//render
return (
<View
style={styles.container}
>
{currScene}
//render我们的tabbarview
</View>
);
}
我们就只差实现我们的tabbarview了,于是我们创建一个view叫TabBar:
/**
* @author YASIN
* @version [PABank V01,17/5/17]
* @date 17/5/17
* @description TabBar
*/
import React,{Component}from 'react';
import {
View,
Animated,
Platform,
StyleSheet,
}from 'react-native';
import Layout from './Layout';
export default class TabBar extends Component{
render(){
return(
<Animated.View
{...this.props}
style={[styles.container,this.props.style]}
>
{this.props.children}
</Animated.View>
);
}
}
const styles=StyleSheet.create({
container:{
position:'absolute',
bottom: 0,
left: 0,
right: 0,
flexDirection: 'row',
justifyContent:'space-around',
height: 49, //跟container的paddingBottom: 49对应
backgroundColor: '#f8f8f8',
alignItems:'center'
}
});
没啥好说的,因为我们在写containerview的时候,当渲染当前view的时候给了一个paddingbottom:
sceneContainer: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
paddingBottom: 49,
backgroundColor: 'gray'
},
因为我们的TabBar是需要放在container的最下方的位置。
好了,创建好了TabBar后,我们就可以引入了:
}
});
//render
return (
<View
style={styles.container}
>
{currScene}
<TabBar>
{/*渲染每一个Tab*/}
</TabBar>
</View>
);
}
然后我们对应每一个Tab创建一个view叫Tab:
/**
* @author YASIN
* @version [PABank V01,17/5/17]
* @date 17/5/17
* @description Tab
*/
import React,{Component,PropTypes}from 'react';
import {
View,
StyleSheet,
Text,
TouchableOpacity,
Image
}from 'react-native';
export default class Tab extends Component{
static propTypes={
...View.propTypes.style,
renderSelectedIcon: PropTypes.func, //选中时渲染的icon
renderIcon: PropTypes.func, //未选中时渲染的icon
titleStyle: Text.propTypes.style, //title的style
titleSelectedStyle: Text.propTypes.style, //title选中时的style
title: PropTypes.string, //title
onPress: PropTypes.func, //点击每个tab的时候
selected: PropTypes.bool //是否选中
}
render(){
let self=this;
return(
<TouchableOpacity
onPress={this.props.onPress}
activeOpacity={0.7}
>
<View style={[styles.container,this.props.style]}>
{function(){
let image=null;
if(!!self.props.selected){
image=self.props.renderSelectedIcon();
}else{
image=self.props.renderIcon();
}
return image;
}()}
<Text style={[this.props.selected?this.props.titleSelectedStyle:this.props.titleStyle,styles.title]}>{this.props.title}</Text>
</View>
</TouchableOpacity>
);
}
}
const styles=StyleSheet.create({
container:{
flexDirection:'column',
alignItems:'center'
},
title:{
fontSize:12,
marginTop: 5
}
});
然后我们在TabNavitator的render中修改代码:
render() {
//获取相应的props内容
let{style,children,sceneStyle,...props}=this.props;
//遍历所有的children
//需要显示的页面跟显示过的页面
let scenes=[];
React.Children.forEach(children,(child,index)=>{
if(child===null){
return;
}
//根据子view获取唯一key
let key=this._getSceneKey(child,index);
let {renderedSceneKeys}=this.state;
//判断该view是不是将要显示的view或者是不是显示过的view
if(!renderedSceneKeys.has(key)){
return;
}
//当前view为选中状态就设置其样式为sceneContainer
let scene=null;
if (child.props.selected) {
scene = (
<View {...child.props} style={styles.sceneContainer} pointerEvents={'auto'} removeClippedSubviews={false}>
{child}
</View>
)
} else {//当前view为未选中状态就设置其样式为hiddenSceneContainer
scene = (
<View {...child.props}style={styles.hiddenSceneContainer} pointerEvents={'none'} removeClippedSubviews={false}>
{child}
</View>
)
}
if(scene!==null)scenes.push(scene);
});
//选出当前需要显示的view
let currScene = null;
scenes.forEach((page, index)=> {
if (page.props.selected) {
currScene = page;
return;
}
});
//render
return (
<View
style={styles.container}
>
{currScene}
<TabBar>
{/*渲染每一个Tab*/}
{React.Children.map(children,this._renderTab)}
</TabBar>
</View>
);
}
_renderTab(item,index){
return(
<Tab
key={index}
renderSelectedIcon={item.props.renderSelectedIcon}
renderIcon={item.props.renderIcon}
titleStyle={item.props.titleStyle}
titleSelectedStyle={item.props.selectedTitleStyle}
title={item.props.title}
onPress={item.props.onPress}
selected={item.props.selected}
></Tab>
);
}
测试代码:
/**
* @author YASIN
* @version [PABank V01,17/5/17]
* @date 17/5/17
* @description TestComponent
*/
import React,{Component}from 'react';
import {
View,
Text,
StyleSheet,
Image
}from 'react-native';
import TabNavitator from './MyTabNavitator';
import * as ScreenUtils from '../../Util/ScreenUtil';
export default class TestComponent extends Component{
// 构造
constructor(props) {
super(props);
// 初始状态
this.state = {
selected: '商家'
};
}
render(){
let self=this;
return(
<TabNavitator>
<TabNavitator.Item
selected={self.state.selected==='我的'}
title='我的'
onPress={self._onItemPress.bind(self,'我的')}
renderIcon={() => <Image style={styles.iconStyle} source={{uri:'icon_tabbar_homepage'}} />}
renderSelectedIcon={() => <Image style={styles.iconStyle} source={{uri:'icon_tabbar_homepage_selected'}} />}
titleStyle={styles.titleStyle}
selectedTitleStyle={styles.selectedTitleStyle}
>
<View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text style={styles.text}>我的</Text></View>
</TabNavitator.Item>
<TabNavitator.Item
selected={self.state.selected==='购物'}
title='购物'
onPress={self._onItemPress.bind(self,'购物')}
renderIcon={() => <Image style={styles.iconStyle} source={{uri:'icon_tabbar_homepage'}} />}
renderSelectedIcon={() => <Image style={styles.iconStyle} source={{uri:'icon_tabbar_homepage_selected'}} />}
titleStyle={styles.titleStyle}
selectedTitleStyle={styles.selectedTitleStyle}
>
<View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text style={styles.text}>购物</Text></View>
</TabNavitator.Item>
<TabNavitator.Item
selected={self.state.selected==='商家'}
title='商家'
onPress={self._onItemPress.bind(self,'商家')}
renderIcon={() => <Image style={styles.iconStyle} source={{uri:'icon_tabbar_homepage'}} />}
renderSelectedIcon={() => <Image style={styles.iconStyle} source={{uri:'icon_tabbar_homepage_selected'}} />}
titleStyle={styles.titleStyle}
selectedTitleStyle={styles.selectedTitleStyle}
>
<View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text style={styles.text}>商家</Text></View>
</TabNavitator.Item>
</TabNavitator>
);
};
_onItemPress(title){
this.setState({
selected: title
});
}
}
const styles=StyleSheet.create({
text:{
color: 'red'
},
iconStyle: {
width: ScreenUtils.scaleSize(40),
height: ScreenUtils.scaleSize(40),
},
selectedTitleStyle: {
color: 'orange'
},
titleStyle: {
fontSize: ScreenUtils.setSpText(10),
color: '#333333'
}
});
好啦~~最后测试就可以看到TabNavitator的效果啦!!!
这节比较快哈~ 因为都没啥可讲的,哈哈~~一起学习一起进步。欢迎入群~~~
本文详细介绍如何使用 React Native 构建自定义 TabNavigator 组件,包括 TabBar 和 Tab 的设计与实现,以及完整的测试代码。

被折叠的 条评论
为什么被折叠?



