設定畫面Navigation
使用 react-navigation (v1)
https://v1.reactnavigation.org/docs/tab-based-navigation.html
前往
src/navigatior.js
設置TabBar中每個TabBar的名稱
{
Home: { screen: Home },
Counter: { screen: Counter },
Camera: { screen: Camera },
PersonalInfo: { screen: PersonalInfo, navigationOptions: { title: '個人資訊' } },
MerchandiseList: { screen: MerchandiseList, navigationOptions: { title: '我的商品' } },
NewMerchandise: { screen: NewMerchandise, navigationOptions: { title: '建立商品' } },
MerchandiseGrid: { screen: MerchandiseGrid, navigationOptions: { title: '商城' } },
MerchandiseDetail: { screen: MerchandiseDetail, navigationOptions: { title: '商品詳細' } }
},
設置TabBar的Icon
對TabNavigator 設置Icon 使用 react-native-vector-icons/FontAwesome
與設置選中(active)與沒選中(inactive)的顏色
{
navigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, tintColor }) => {
const { routeName } = navigation.state;
const ICON_MAP = {
PersonalInfo: 'user',
MerchandiseList: 'archive',
NewMerchandise: 'plus',
MerchandiseGrid: 'th',
MerchandiseDetail: 'info-circle'
};
// You can return any component that you like here! We usually use an
// icon component from react-native-vector-icons
return <Icon name={ICON_MAP[routeName] || ''} size={24} color={tintColor} />;
}
}),
tabBarOptions: {
activeTintColor: 'tomato',
inactiveTintColor: 'gray'
},
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false
}
調整TabBar 的高度與Tab中 每個TabBar的文字大小
在tabBarOptions
中 加入style
const styles = StyleSheet.create({
tabBar: {
height: 90
},
tabLabel: {
fontSize: 16
}
});
...
tabBarOptions: {
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
style: styles.tabBar,
labelStyle: styles.tabLabel
},
將某些畫面不在TabNavigator 中出現
例如相機這是由某個頁面的動作去開啟的行為,不應該在TabBar中出現,使用StackNavigator 包住原本的AppNavigator,並把那些需要全螢幕的畫面放置在StackNavigator中
const RootNavigator = new StackNavigator(
{
App: { screen: AppNavigator },
Home: { screen: Home },
Counter: { screen: Counter },
Camera: { screen: Camera }
},
{
headerMode: 'none'
}
);
還有部分畫面是屬於某個頁面開啟,但它還是需要TabBar在下面進行操作,因為那些畫面屬於商城的一部分,譬如說個人頁面->上傳商品->商品管理這樣的操作路徑,這時候我們可以在某個Tab頁面的screen放置StackNavigator
來做到此事
{
PersonalInfo: {
screen: new StackNavigator({
PersonalInfo: { screen: PersonalInfo, navigationOptions: { title: '商品清單' } },
MerchandiseList: { screen: MerchandiseList, navigationOptions: { title: '我的商品' } },
NewMerchandise: { screen: NewMerchandise, navigationOptions: { title: '建立商品' } }
}),
navigationOptions: { title: '個人資訊' }
},
MerchandiseGrid: { screen: MerchandiseGrid, navigationOptions: { title: '商城' } },
MerchandiseDetail: {
screen: MerchandiseDetail,
navigationOptions: { title: '商品詳細', tabBarVisible: false }
}
},
新增BadgeIcon
可以自由發揮layout 的技巧,以下是參考範例
以
numberOfBadges
做為傳入參數,代表有幾則通知以setParams 的方式來傳遞numberOfBadges
const styles = StyleSheet.create({ .... badge: { position: 'absolute', right: -20, top: -10, borderRadius: 15, width: 30, height: 30, backgroundColor: '#e12', color: 'white', textAlign: 'center', fontSize: 20 } }); const BadgeIcon = (props) => { const { numberOfBadges } = props; const show = !!numberOfBadges; return ( <View> <Icon {...props} /> {show && <Text style={styles.badge}> {`${numberOfBadges}`}</Text>} </View> ); };
更新其他頁面的通知數量
透過setParams
但只能更新自己,因為每個頁面都有屬於自己的route params
因為react-navigation 有跟redux store 做結合,將想更新的值打到store 內,用key指定要更新的store name e.g.
TransactionRecord
在navigationOptions 中來接收
const setParamsAction = NavigationActions.setParams({ params: { numberOfBadges: result }, key: 'TransactionRecord' }); this.props.navigation.dispatch(setParamsAction);
navigationOptions: ({ navigation }) => ({
tabBarIcon: ({ tintColor }) => {
const { routeName } = navigation.state;
const ICON_MAP = {
PersonalInfo: 'user',
MerchandiseList: 'archive',
NewMerchandise: 'plus',
MerchandiseGrid: 'th',
MerchandiseDetail: 'info-circle',
TransactionRecord: 'list',
ShoppingCart: 'shopping-cart'
};
// You can return any component that you like here! We usually use an
// icon component from react-native-vector-icons
const routeParams = navigation.state.params || {};
return (
<BadgeIcon
name={ICON_MAP[routeName] || ''}
size={42}
color={tintColor}
numberOfBadges={routeParams.numberOfBadges}
/>
);
}
})
部分頁面關掉TabBar顯示或是部分頁面打開 StackNavigator's Header
headerMode - Specifies how the header should be rendered:
float - Render a single header that stays at the top and animates as screens are changed. This is a common pattern on iOS.
screen - Each screen has a header attached to it and the header fades in and out together with the screen. This is a common pattern on Android.
const AppNavigator = new TabNavigator(
{
MerchandiseGrid: new StackNavigator(
{
MerchandiseGrid: {
screen: MerchandiseGrid,
navigationOptions: { title: '商城', header: null } // disable header but open all headers in here
},
MerchandiseDetail: {
screen: MerchandiseDetail,
navigationOptions: { title: '商品詳細', tabBarVisible: false }
}
},
{
headerMode: 'screen'
}
),
}
參考資料:
https://github.com/react-navigation/react-navigation/issues/293#issuecomment-279146748
https://github.com/react-navigation/react-navigation/issues/608
Why console.log slow
Last updated
Was this helpful?