React Native【实战范例】弹跳动画菜单导航

最终效果

范例代码

c 复制代码
import React, { useEffect, useRef, useState } from "react";
import {
  Animated,
  Easing,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from "react-native";
export default function Demo() {
  const width1 = useRef(new Animated.Value(200)).current;
  const width2 = useRef(new Animated.Value(64)).current;
  const width3 = useRef(new Animated.Value(64)).current;
  const width4 = useRef(new Animated.Value(64)).current;
  const [index, setIndex] = useState(0);
  useEffect(() => {
    anim1(index === 0);
    anim2(index === 1);
    anim3(index === 2);
    anim4(index === 3);
  }, [index]);
  const anim1 = (isOpen) => {
    Animated.timing(width1, {
      toValue: isOpen ? 200 : 64,
      duration: isOpen ? 500 : 300,
      easing: isOpen ? Easing.elastic(3) : Easing.ease,
      useNativeDriver: false,
    }).start();
  };
  const anim2 = (isOpen) => {
    Animated.timing(width2, {
      toValue: isOpen ? 200 : 64,
      duration: isOpen ? 500 : 300,
      easing: isOpen ? Easing.elastic(3) : Easing.ease,
      useNativeDriver: false,
    }).start();
  };
  const anim3 = (isOpen) => {
    Animated.timing(width3, {
      toValue: isOpen ? 200 : 64,
      duration: isOpen ? 500 : 300,
      easing: isOpen ? Easing.elastic(3) : Easing.ease,
      useNativeDriver: false,
    }).start();
  };
  const anim4 = (isOpen) => {
    Animated.timing(width4, {
      toValue: isOpen ? 200 : 64,
      duration: isOpen ? 500 : 300,
      easing: isOpen ? Easing.elastic(3) : Easing.ease,
      useNativeDriver: false,
    }).start();
  };
  return (
    <View style={styles.root}>
      <TouchableOpacity
        activeOpacity={0.8}
        onPress={() => {
          setIndex(0);
        }}
      >
        <Animated.View
          style={[
            styles.view,
            { width: width1, opacity: index === 0 ? 1 : 0.75 },
          ]}
        >
          <Text style={styles.txt} numberOfLines={1} ellipsizeMode="clip">
            首页推荐
          </Text>
          <View style={styles.dot} />
        </Animated.View>
      </TouchableOpacity>
      <TouchableOpacity
        activeOpacity={0.8}
        onPress={() => {
          setIndex(1);
        }}
      >
        <Animated.View
          style={[
            styles.view,
            { width: width2, opacity: index === 1 ? 1 : 0.75 },
          ]}
        >
          <Text style={styles.txt} numberOfLines={1} ellipsizeMode="clip">
            热门直播
          </Text>
          <View style={styles.dot} />
        </Animated.View>
      </TouchableOpacity>
      <TouchableOpacity
        activeOpacity={0.8}
        onPress={() => {
          setIndex(2);
        }}
      >
        <Animated.View
          style={[
            styles.view,
            { width: width3, opacity: index === 2 ? 1 : 0.75 },
          ]}
        >
          <Text style={styles.txt} numberOfLines={1} ellipsizeMode="clip">
            我的礼物
          </Text>
          <View style={styles.dot} />
        </Animated.View>
      </TouchableOpacity>
      <TouchableOpacity
        activeOpacity={0.8}
        onPress={() => {
          setIndex(3);
        }}
      >
        <Animated.View
          style={[
            styles.view,
            { width: width4, opacity: index === 3 ? 1 : 0.75 },
          ]}
        >
          <Text style={styles.txt} numberOfLines={1} ellipsizeMode="clip">
            个人信息
          </Text>
          <View style={styles.dot} />
        </Animated.View>
      </TouchableOpacity>
    </View>
  );
}
const styles = StyleSheet.create({
  root: {
    width: "100%",
    height: "100%",
    backgroundColor: "white",
    flexDirection: "column",
    justifyContent: "center",
  },
  view: {
    height: 60,
    flexDirection: "row",
    alignItems: "center",
    marginVertical: 16,
    borderTopRightRadius: 28,
    borderBottomRightRadius: 28,
    backgroundColor: "#2030ff",
    paddingLeft: 16,
    overflow: "hidden",
  },
  img: {
    width: 32,
    height: 32,
    tintColor: "white",
  },
  txt: {
    fontSize: 18,
    color: "#ffffffD0",
    marginLeft: 16,
  },
  dot: {
    width: 10,
    height: 10,
    backgroundColor: "#20f020",
    marginLeft: 28,
    borderRadius: 5,
  },
});
相关推荐
2401_860319522 小时前
在React Native中开发一个轮播组件(Swipe轮播),通过组件react-native-snap-carousel来实现
javascript·react native·react.js
2401_860319522 小时前
在React Native中,开发自定义组件(例如一个`Tag`组件)通常涉及到创建React组件,并且实现一个点击事件处理器
javascript·react native·react.js
鸡吃丸子2 天前
React Native入门详解
开发语言·前端·javascript·react native·react.js
LisEcho2 天前
yoyoj-rn — RN 的脚手架工具可以不是 @react-native-community/cli
前端·react native·npm
笨小孩7872 天前
Flutter跨平台开发全解析:从原理到实战的深度指南
javascript·react native·react.js
前端不太难4 天前
RN 调试效率低,一点小改动就需要重新构建?解决手册(实战 / 脚本 / Demo)
前端·react native·重构
前端不太难4 天前
RN 的导航体系太混乱,如何选型和架构设计?
前端·react native·架构
乖女子@@@4 天前
01ReactNative-环境搭建
javascript·react native·react.js
wayne2145 天前
ReactNative0.83正式发布 —— 更强DevTools体验与Web API拓展
react native