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,
  },
});
相关推荐
lbb 小魔仙9 小时前
【HarmonyOS实战】OpenHarmony + RN:自定义 useFormik 表单处理
react native·harmonyos
果粒蹬i12 小时前
【HarmonyOS】DAY8:React Native for OpenHarmony 实战:多端响应式布局与高可用交互设计
react native·交互·harmonyos
摘星编程1 天前
React Native鸿蒙版:Image图片占位符
react native·react.js·harmonyos
飞羽殇情1 天前
基于React Native鸿蒙跨平台开发构建完整电商预售系统数据模型,完成参与预售、支付尾款、商品信息展示等
react native·react.js·华为·harmonyos
摘星编程1 天前
React Native + OpenHarmony:ImageSVG图片渲染
javascript·react native·react.js
摘星编程1 天前
OpenHarmony + RN:Text文本书写模式
javascript·react native·react.js
摘星编程1 天前
用React Native开发OpenHarmony应用:Image网络图片加载
javascript·react native·react.js
摘星编程1 天前
OpenHarmony环境下React Native:ImageBase64图片显示
javascript·react native·react.js
摘星编程1 天前
React Native鸿蒙:Image本地图片显示
javascript·react native·react.js
2501_921930831 天前
基础入门 React Native 鸿蒙跨平台开发:Video 全屏播放与画中画 鸿蒙实战
react native·react.js·harmonyos