前言
? 接觸過ReactNative(以下簡稱RN)的大概都知道,react-navigation提供了兩種開箱即用的導航欄組件
- createBottomTabNavigator
- createMaterialBottomTabNavigator
分別是這樣的
盡管官方提供了導航欄的開箱即用方案,但是實際開發里面,我們會遇到各種各樣的導航欄,各種各樣的動效,所以以上可能無法滿足我們的開發需求,我們就需要定制化的去做我們導航欄
例如我們UI給我的導航欄樣式
我的內心: 這他么中間凸起的我怎么做,老子只是一個小前端,app很渣啊啊啊
借助可愛的google,我找到了解決方法
就是
TabBarComponent
這個api在文檔資料很少,所以想要知道怎么用只能通過網絡上的資源了
其中深受這篇文案的啟發
Let's Create A Custom Animated Tab Bar With React Native
這位外國友人(話說reactnative在國外似乎還有點火),借助動畫庫react-native-pose
,完成了這樣的效果
雖然是英文博客,但是配合翻譯基本閱讀無障礙,借助他的博客,我完成了ReactNative的自定義導航欄,效果如下
自定義底部導航欄
- 自定義底部導航欄是基于
createBottomTabNavigator
,所以我們使用這個api來創建底部導航欄- 指定
createBottomTabNavigator
的tabBarComponent- tabBarComponent內部進行底部導航欄的編寫
增加底部導航器
import React from 'react'
import { createBottomTabNavigator } from 'react-navigation'
import Icon from '../Common/Icon' // 自定義圖標庫
import TabBar from '../Common/TabBar' // tabBarComponent 自定義組件
// 頁面
import Category from '../View/TabBar/Category/Category'
import Main from '../View/TabBar/Main/Main'
import My from '../View/TabBar/My/My'
import OrderList from '../View/TabBar/OrderList/OrderList'
import OnlineDoctor from '../View/TabBar/OnlineDoctor/OnlineDoctor'
export default createBottomTabNavigator({// 首頁:one: {screen: Main,navigationOptions: () => {return {tabBarIcon: ({ tintColor }) => {var soureImgeif (tintColor == '#CBCBCB') {soureImge = 'main'} else {soureImge = 'mainActive'}return <Icon name={soureImge} size={26} color={tintColor} />}}}},//分類:two: {screen: Category,navigationOptions: {tabBarIcon: ({ tintColor }) => {var soureImgeif (tintColor == '#CBCBCB') {soureImge = 'Category'} else {soureImge = 'CategoryActive'}return <Icon name={soureImge} size={26} color={tintColor} />}}},//問診:three: {screen: OnlineDoctor,navigationOptions: {tabBarIcon: ({ tintColor }) => {var soureImgeif (tintColor == '#CBCBCB') {soureImge = 'onLine'} else {soureImge = 'onLineActive'}return <Icon name={soureImge} size={48} color={tintColor} />}}},// 購物籃: four: {screen: OrderList,navigationOptions: {tabBarIcon: ({ tintColor }) => {var soureImgeif (tintColor == '#CBCBCB') {soureImge = 'OrderList'} else {soureImge = 'OrderListActive'}return <Icon name={soureImge} size={26} color={tintColor} />}}},//我的:five: {screen: My,navigationOptions: () => {return {tabBarIcon: ({ tintColor }) => {var soureImgeif (tintColor == '#CBCBCB') {soureImge = 'My'} else {soureImge = 'MyActive'}return <Icon name={soureImge} size={26} color={tintColor} />}}}}},{initialRouteName: 'one', // 初始化頁面tabBarComponent: TabBar,tabBarOptions: {activeTintColor: '#F34C56',inactiveTintColor: '#CBCBCB'}}
)復制代碼
工具函數
圖標沒有使用圖標庫,直接搞一個圖標庫比較得心應手
../Common/Icon.js
import React from 'react'
import { Image } from 'react-native'
import { TabIcon } from './Image'const Icon = ({ name, style, size }) => {const icon = TabIcon[name]return (<Imagesource={icon}style={[{ width: size, height: size }, style]}/>)
}export default Icon
復制代碼
而對于圖片則進行統一管理
../Common/Image.js
/*** 所有的圖片資源都從這里統一管理*/
// 底部導航欄的圖片資源
export const TabIcon = {main: require('..'),mainActive: require('..'),Category: require('..'),CategoryActive: require('..'),onLine: require('..'),onLineActive: require('..'),OrderList: require('..'),OrderListActive: require('..'),My: require('..'),MyActive: require('..'),
}
復制代碼
自定義底部導航器
萬事俱備,下面就是自定義底部導航器了,就和定義React
組件一樣
import React from 'react'
import {View,Text,StyleSheet,TouchableOpacity,TouchableNativeFeedback,Dimensions
} from 'react-native'
import posed from 'react-native-pose' // react-native 動畫庫const Scaler = posed.View({ // 定義點擊縮放active: { scale: 1 },inactive: { scale: 0.9 }
})const TabBar = props => {const {renderIcon,getLabelText,activeTintColor,inactiveTintColor,onTabPress,onTabLongPress,getAccessibilityLabel,navigation} = propsconst { routes, index: activeRouteIndex } = navigation.statereturn (<Scaler style={Styles.container}>{routes.map((route, routeIndex) => {const isRouteActive = routeIndex === activeRouteIndexconst tintColor = isRouteActive ? activeTintColor : inactiveTintColorreturn (<TouchableNativeFeedbackkey={routeIndex}style={Styles.tabButton}onPress={() => {onTabPress({ route })}}onLongPress={() => {onTabLongPress({ route })}}accessibilityLabel={getAccessibilityLabel({ route })}>{route.key == 'three' ? ( // 對特殊圖標進行特殊處理<Scalerstyle={Styles.scalerOnline}pose={isRouteActive ? 'active' : 'inactive'}>{renderIcon({ route, focused: isRouteActive, tintColor })}<Text style={Styles.iconText}>{getLabelText({ route })}</Text></Scaler>) : ( // 普通圖標普通處理<Scalerstyle={Styles.scaler}pose={isRouteActive ? 'active' : 'inactive'}>{renderIcon({ route, focused: isRouteActive, tintColor })}<Text style={Styles.iconText}>{getLabelText({ route })}</Text></Scaler>)}</TouchableNativeFeedback>)})}</Scaler>)
}const Styles = StyleSheet.create({container: {flexDirection: 'row',height: 53,borderWidth: 1,borderRadius: 1,borderColor: '#EEEEEE',shadowOffset: { width: 5, height: 10 },shadowOpacity: 0.75,elevation: 1},tabButton: {flex: 1,justifyContent: 'center',alignItems: 'center'},spotLight: {width: tabWidth,height: '100%',justifyContent: 'center',alignItems: 'center'},spotLightInner: {width: 48,height: 48,backgroundColor: '#ee0000',borderRadius: 24},scaler: {flex: 1,alignItems: 'center',justifyContent: 'center',},scalerOnline: {flex: 1,alignItems: 'center',justifyContent: 'flex-end',},iconText: {fontSize: 12,lineHeight: 20}
})export default TabBar
復制代碼
最后實現的效果就是
如果你也有這樣的需求,可以看看老外發布的那篇博客
Let's Create A Custom Animated Tab Bar With React Native
最后: 快要過年了,祝大家新年快樂