react native踩坑日记(2):react-native + react-navigation 实现底部导航点击动画

我也是一个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中,可在下方代码中查看

这里就不再讲解AnimatedEasing如何使用了,有需要请自行查阅

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,
  },
});

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

琞、小菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值