React Native 實現基於react-native-tab-navigator庫Tab切換封裝
阿新 • • 發佈:2019-01-22
react-native-tab-navigator是一款Tab切換的庫,細心的讀者可能注意到了對於TabNavigator.Item選項卡部分,程式碼功能上基本上是重複的,對此,我們能不能對這種有相同功能的程式碼進行二次封裝呢?
程式碼示例
新建專案,並安裝react-native-tab-navigator庫支援
npm install react-native-tab-navigator –save
主頁面封裝
首先我們可以將功能的部分抽出來。
<TabNavigatorItem
selected={this.state.selectedTab===tabName}
title={title}
titleStyle={styles.tabText}
selectedTitleStyle={styles.selectedTabText}
renderIcon={()=><Image style={styles.icon} source={tabNomal}/>}
renderSelectedIcon={()=><Image style={styles.icon} source={tabPress}/>}
onPress={()=>this.onPress(tabName)}
renderBadge={()=>isBadge?<View style={styles.badgeView}><Text style={styles.badgeText}>15</Text></View>:null}
>
<View style={styles.page}>
<Text>{tabContent}</Text>
</View>
</TabNavigatorItem>
接下來我們需要構造一個函式,用來接收不同情況下Tab子選項卡。
switch (tabName) {
case 'Home':
tabNomal=TAB_HOME_NORMAL;
tabPress=TAB_HOME_PRESS;
break;
case 'Mine':
tabNomal=TAB_MINE_NORMAL;
tabPress=TAB_MINE_PRESS;
break;
default:
}
所以構造的完整的程式碼如:
//名稱,圖示,子檢視文字,選中狀態
renderTabView(title,tabName,tabContent,isBadge){
var tabNomal;
var tabPress;
switch (tabName) {
case 'Home':
tabNomal=TAB_HOME_NORMAL;
tabPress=TAB_HOME_PRESS;
break;
case 'Mine':
tabNomal=TAB_MINE_NORMAL;
tabPress=TAB_MINE_PRESS;
break;
default:
}
return(
<TabNavigatorItem
selected={this.state.selectedTab===tabName}
title={title}
titleStyle={styles.tabText}
selectedTitleStyle={styles.selectedTabText}
renderIcon={()=><Image style={styles.icon} source={tabNomal}/>}
renderSelectedIcon={()=><Image style={styles.icon} source={tabPress}/>}
onPress={()=>this.onPress(tabName)}
renderBadge={()=>isBadge?<View style={styles.badgeView}><Text style={styles.badgeText}>15</Text></View>:null}
>
<View style={styles.page}>
<Text>{tabContent}</Text>
</View>
</TabNavigatorItem>
);
}
其實到此,我們已經實現了封裝,在使用的時候按如下方式直接使用即可:
{this.renderTabView('首頁','Home','首頁模組',true)}
但是,我們對上面的內容還可以進一步的封裝:
tabBarView(){
return (
<TabNavigator
tabBarStyle={styles.tab}>
{renderTabView('首頁','Home','首頁模組',true)}
{renderTabView('我的','Mine','我的模組',false)}
</TabNavigator>
);
}
然後,我們在render()只需要簡單的呼叫即可:
render() {
var tabView=tabBarView();
return (
<View style={styles.container}>
{tabView}
</View>
);
}
那麼完整的程式碼如下:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import TabNavigator from 'react-native-tab-navigator';
import HomeScreen from './src/widght/HomeScreen';
import MineScreen from './src/widght/MineScreen';
import {
AppRegistry,
StyleSheet,
Text,
Image,
View
} from 'react-native';
const TabNavigatorItem =TabNavigator.Item;
//預設選項
const TAB_HOME_NORMAL=require('./image/tabbar_homepage.png');
const TAB_MINE_NORMAL=require('./image/tabbar_mine.png');
//選中
const TAB_HOME_PRESS=require('./image/tabbar_homepage_selected.png');
const TAB_MINE_PRESS=require('./image/tabbar_mine_selected.png');
export default class HelloWord extends Component {
//預設選中
constructor(){
super();
this.state={
selectedTab:'Home',
}
}
//點選方法
onPress(tabName){
if(tabName){
this.setState({
selectedTab:tabName,
}
);
}
}
//渲染選項卡
renderTabView(title,tabName,defaultTab,isBadge){
var tabNomal;
var tabPress;
var tabPage;
switch (tabName) {
case 'Home':
tabNomal=TAB_HOME_NORMAL;
tabPress=TAB_HOME_PRESS;
tabPage=<HomeScreen/>;
break;
case 'Mine':
tabNomal=TAB_MINE_NORMAL;
tabPress=TAB_MINE_PRESS;
tabPage=<MineScreen/>;
break;
default:
}
return(
<TabNavigatorItem
selected={this.state.selectedTab===tabName}
title={title}
titleStyle={styles.tabText}
selectedTitleStyle={styles.selectedTabText}
renderIcon={()=><Image style={styles.icon} source={tabNomal}/>}
renderSelectedIcon={()=><Image style={styles.icon} source={tabPress}/>}
onPress={()=>this.onPress(tabName)}
renderBadge={()=>isBadge?<View style={styles.badgeView}><Text style={styles.badgeText}>15</Text></View>:null}
>
<View style={styles.page}>
{tabPage}
</View>
</TabNavigatorItem>
);
}
//自定義TabView
tabBarView(){
return (
<TabNavigator
tabBarStyle={styles.tab}>
{this.renderTabView('首頁','Home',HomeScreen,true)}
{this.renderTabView('我的','Mine',HomeScreen,false)}
</TabNavigator>
);
}
//渲染介面
render() {
var tabView=this.tabBarView();
return (
<View style={styles.container}>
{tabView}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
tabText: {
fontSize: 10,
color: 'black'
},
selectedTabText: {
fontSize: 10,
color: 'green'
},
tabIcon:{
width:25,
height:25,
},
badgeView:{
width:22,
height:14 ,
backgroundColor:'#f85959',
borderWidth:1,
marginLeft:10,
marginTop:3,
borderColor:'#FFF',
alignItems:'center',
justifyContent:'center',
borderRadius:8,
},
badgeText:{
color:'#ffffff',
fontSize:8,
},
icon: {
width: 22,
height: 22
},
page: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#FFFFFF'
},
});
AppRegistry.registerComponent('HelloWord', () => HelloWord);
標題欄封裝
接下來我們對標題欄進行封裝,注意,標題是變化的,這時候我們想到給Text的props設定動態屬性。在使用的時候直接簡單的呼叫下即可。
<Header text='首頁'> </Header>
完整程式碼:
/**
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import { View, Text,StyleSheet} from 'react-native';
var Dimensions = require('Dimensions');
var ScreenWidth = Dimensions.get('window').width;
class Header extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.text }>{this.props.text || "標題頭"}</Text>
<Text style={styles.diviceLine}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
width:ScreenWidth,
marginTop:20,
height:50,
alignItems:'center', /*水平居中*/
justifyContent:'center',/*垂直居中*/
backgroundColor: '#FFFFFF',
flexDirection:'column'
},
text: {
fontSize: 18,
color:'#000000',
textAlign:'center'
},
diviceLine: {
backgroundColor: '#e9e9e9',
height: 1,
}
});
export default Header;