接觸過ReactNative(如下簡稱RN)的大概都知道,react-navigation提供了兩種開箱即用的導航欄組件html
分別是這樣的前端
儘管官方提供了導航欄的開箱即用方案,可是實際開發裏面,咱們會遇到各類各樣的導航欄,各類各樣的動效,因此以上可能沒法知足咱們的開發需求,咱們就須要定製化的去作咱們導航欄react
例如咱們UI給個人導航欄樣式react-native
個人心裏: 這他麼中間凸起的我怎麼作,老子只是一個小前端,app很渣啊啊啊api
藉助可愛的google,我找到了解決方法網絡
就是app
這個api在文檔資料不多,因此想要知道怎麼用只能經過網絡上的資源了函數
其中深受這篇文案的啓發工具
Let's Create A Custom Animated Tab Bar With React Nativeflex
這位外國友人(話說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 soureImge
if (tintColor == '#CBCBCB') {
soureImge = 'main'
} else {
soureImge = 'mainActive'
}
return <Icon name={soureImge} size={26} color={tintColor} />
}
}
}
},
//分類:
two: {
screen: Category,
navigationOptions: {
tabBarIcon: ({ tintColor }) => {
var soureImge
if (tintColor == '#CBCBCB') {
soureImge = 'Category'
} else {
soureImge = 'CategoryActive'
}
return <Icon name={soureImge} size={26} color={tintColor} />
}
}
},
//問診:
three: {
screen: OnlineDoctor,
navigationOptions: {
tabBarIcon: ({ tintColor }) => {
var soureImge
if (tintColor == '#CBCBCB') {
soureImge = 'onLine'
} else {
soureImge = 'onLineActive'
}
return <Icon name={soureImge} size={48} color={tintColor} />
}
}
},
// 購物籃:
four: {
screen: OrderList,
navigationOptions: {
tabBarIcon: ({ tintColor }) => {
var soureImge
if (tintColor == '#CBCBCB') {
soureImge = 'OrderList'
} else {
soureImge = 'OrderListActive'
}
return <Icon name={soureImge} size={26} color={tintColor} />
}
}
},
//個人:
five: {
screen: My,
navigationOptions: () => {
return {
tabBarIcon: ({ tintColor }) => {
var soureImge
if (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 (
<Image source={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
} = props
const { routes, index: activeRouteIndex } = navigation.state
return (
<Scaler style={Styles.container}> {routes.map((route, routeIndex) => { const isRouteActive = routeIndex === activeRouteIndex const tintColor = isRouteActive ? activeTintColor : inactiveTintColor return ( <TouchableNativeFeedback key={routeIndex} style={Styles.tabButton} onPress={() => { onTabPress({ route }) }} onLongPress={() => { onTabLongPress({ route }) }} accessibilityLabel={getAccessibilityLabel({ route })} > {route.key == 'three' ? ( // 對特殊圖標進行特殊處理 <Scaler style={Styles.scalerOnline} pose={isRouteActive ? 'active' : 'inactive'} > {renderIcon({ route, focused: isRouteActive, tintColor })} <Text style={Styles.iconText}>{getLabelText({ route })}</Text> </Scaler> ) : ( // 普通圖標普通處理 <Scaler style={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
最後: 快要過年了,祝你們新年快樂