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,
  },
});
相关推荐
摘星编程9 小时前
React Native for OpenHarmony 实战:Linking 链接处理详解
javascript·react native·react.js
摘星编程9 小时前
React Native for OpenHarmony 实战:DatePickerAndroid 日期选择器详解
android·react native·react.js
摘星编程10 小时前
React Native for OpenHarmony 实战:ImageBackground 背景图片详解
javascript·react native·react.js
摘星编程11 小时前
React Native for OpenHarmony 实战:Alert 警告提示详解
javascript·react native·react.js
摘星编程12 小时前
React Native for OpenHarmony 实战:GestureResponderSystem 手势系统详解
javascript·react native·react.js
lili-felicity12 小时前
React Native for OpenHarmony 实战:加载效果的实现详解
javascript·react native·react.js·harmonyos
哈哈你是真的厉害12 小时前
React Native 鸿蒙跨平台开发:BaseConverter 进制转换
react native·react.js·harmonyos
lili-felicity13 小时前
React Native for OpenHarmony 实战:Easing 动画完全指南
javascript·react native·react.js
2501_9481226314 小时前
React Native for OpenHarmony 实战:Steam 资讯 App 服务条款实现
javascript·react native·react.js·游戏·ecmascript·harmonyos
lili-felicity18 小时前
React Native for HarmonyOS (鸿蒙) 实战精讲:2D/3D 变换全场景
react native·3d·harmonyos