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,
  },
});
相关推荐
sealaugh322 小时前
react native(学习笔记第三课) 英语打卡微应用(2)-从上传图片开始
笔记·学习·react native
空中海3 小时前
05 React Native架构设计、主线项目与专家实践
javascript·react native·react.js
一个扣子2 天前
降低 Android APK 体积:Hermes 的字节码格式与资源压缩
react native·字节码·构建优化·包体积优化·android性能·hermes·apk瘦身
cn_mengbei3 天前
用React Native开发OpenHarmony应用:Reanimated共享元素过渡
javascript·react native·react.js
祖国的好青年5 天前
VS Code 搭建 React Native 开发环境(Windows 实战指南)
android·windows·react native·react.js
一个扣子5 天前
性能面板解读:通过 Hermes Runtime 测量函数执行耗时
react native·chrome devtools·hermes·性能面板·函数耗时·performance api
一个扣子7 天前
Hermes 的 Android 与 iOS 平台差异化配置详解
react native·字节码·新架构·hermes·android配置·ios配置·平台差异
茅盾体7 天前
React Native
android·react native·react.js
一个扣子8 天前
多环境配置:开发/生产环境下 Hermes 的开启与关闭策略
react native·开发模式·多环境配置·生产模式·hermes·环境切换·构建配置
TechMasterPlus9 天前
Hermes 深度解析:React Native 高性能 JavaScript 引擎实践指南
javascript·react native·react.js