我也是一个RN初学者,而且钻研的不是很深,如果你想要在这看到深入原理,针对每一个细节都有详细解读的话那你可以另寻他处,我这只能满足普通的业务需要。不会讲述每一个点如何使用,只是提供一个可以突破的点,怎么做可以去实现。
趁着项目还在启动,整理一下如何使用react-navigation的createBottomTabNavigator
创建底部导航时增加上点击动画。
实际是一个很简单的功能,但是不知道为什么被我搞了一天,快下班了灵光一闪给整出来了。
不需要借助npm
包什么的,只需要用到RN的Animated, Easing
即可。
首先,你要知道如何使用react-navigation
创建底部导航,这个有很多文档和学习视频可以去学习一下,目前react-navigation
最新官方版本是5.X,但是很多学习资料与文档都是4.X的,4与5是有一点的区别的,本文使用的是4.X
思路:createBottomTabNavigator
创建底部tab时,可以使用navigationOptions
定义底部tab的标题样式等,其中tabBarIcon
是可以自定义的,所以我们把需要有动画的元素放入tabBarIcon
中,可在下方代码中查看
这里就不再讲解Animated
和Easing
如何使用了,有需要请自行查阅
import React, {Component} from 'react';
import {createBottomTabNavigator} from 'react-navigation-tabs';
import {createAppContainer} from 'react-navigation';
import My_false from '../page/source/A.png';
import My_true from '../page/source/wode.png';
import Home_false from '../page/source/home.png';
import Home_true from '../page/source/home2.png';
import {View, Animated, Easing, Image, StyleSheet, Text} from 'react-native';
export default class AppBottomTabNavigator extends Component {
constructor(props) {
super(props);
this.moveAnim = new Animated.Value(0);
}
componentDidMount() {
this.startAnimation();
}
startAnimation = () => {
this.moveAnim.setValue(0);
Animated.timing(this.moveAnim, {
toValue: 1,
duration: 100,
easing: Easing.linear,
useNativeDriver: true,
}).start();
};
_tabNavigator() {
return createAppContainer(
createBottomTabNavigator(
{
ChartList: {
screen: MessageList,
navigationOptions: {
tabBarLabel: '最近聊天',
tabBarIcon: ({tintColor, focused}) => {
this.startAnimation();
return (
<View>
{focused ? (
<Animated.View
style={[
styles.btnBox,
{
transform: [
{
scaleY: this.moveAnim.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
}),
},
{
scaleX: this.moveAnim.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
}),
},
],
},
]}>
<Image
style={styles.selectedIcon}
source={Home_false}
/>
<Text style={styles.btnColor}>最近聊天</Text>
</Animated.View>
) : (
<Image style={styles.icon} source={Home_true} />
)}
</View>
);
},
},
},
TrendingPage: {
screen: TrendingPage,
navigationOptions: {
tabBarLabel: '联系人',
tabBarIcon: ({tintColor, focused}) => {
return (
<View>
{focused ? (
<Animated.View
style={[
styles.btnBox,
{
transform: [
{
scaleY: this.moveAnim.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
}),
},
{
scaleX: this.moveAnim.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
}),
},
],
},
]}>
<Image style={styles.selectedIcon} source={My_false} />
<Text style={styles.btnColor}>联系人'</Text>
</Animated.View>
) : (
<Image style={styles.icon} source={My_true} />
)}
</View>
);
},
},
},
},
{
tabBarOptions: {
activeTintColor: 'red',
showLabel: false,
},
},
),
);
}
render() {
const Tab = this._tabNavigator();
NavigationUtil.navigation = this.props.navigation;
return <Tab />;
}
}
const styles = StyleSheet.create({
btn: {
width: 100,
height: 50,
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
},
btnBox: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
width: 120,
height: 35,
borderRadius: 20,
shadowOffset: {width: 1, height: 1},
shadowOpacity: 0.3,
shadowRadius: 2,
elevation: 1,
},
selectedIcon: {
width: 20,
height: 20,
},
icon: {
width: 40,
height: 40,
},
btnColor: {
color: '#fff',
fontWeight: '600',
fontSize: 16,
},
});