分享下这个课后作业手风琴菜单效果,

来源:9-13 课后作业练习

vscode

2024-12-23

看了下老师的源码,是分开写的,我是写一个数组里面,分享下

import React, { useRef, useState } from "react";
import { View, Text, StyleSheet, TouchableOpacity, Animated, Image, Easing } from "react-native";

import icon_gift from './images/icon_gift.png';
import icon_mine from './images/icon_mine.png';
import icon_home from './images/icon_home.png';
import icon_show from './images/icon_show.png';

export default () => {

    const [index, setIndex] = useState(0);

    const menuList = [
        {
            name: '首页推荐',
            icon: icon_home,
            width: useRef(new Animated.Value(200)).current,
        },
        {
            name: '热门直播',
            icon: icon_show,
            width: useRef(new Animated.Value(64)).current,
        },
        {
            name: '我的礼物',
            icon: icon_gift,
            width: useRef(new Animated.Value(64)).current,
        },
        {
            name: '个人信息',
            icon: icon_mine,
            width: useRef(new Animated.Value(64)).current,
        },
    ]
    return (
        <View style={styles.root}>
            {
                menuList.map((item, i) => {
                    return (<TouchableOpacity key={i}
                        onPress={() => {
                            setIndex(i);
                            // 循环把所有菜单收缩,
                            menuList.forEach((curItem) => {
                                Animated.timing(curItem.width, {
                                    toValue: 64,
                                    duration: 300,
                                    easing: Easing.ease,
                                }).start();
                            })
                            // 把当前展开
                            Animated.timing(item.width, {
                                toValue: 200,
                                easing: Easing.elastic(3),
                                duration: 500,
                            }).start();
                        }}>
                        <Animated.View style={[styles.animatedView, {
                            width: item.width,
                            opacity: index === i ? 1 : 0.75
                        }]}>
                            <Image style={styles.image} source={item.icon}></Image>
                            <Text style={styles.text}>{item.name}</Text>
                            {
                                index === i && <View style={styles.dot}></View>
                            }
                        </Animated.View>
                    </TouchableOpacity>)
                })
            }
        </View>
    )
}

const styles = StyleSheet.create({
    root: {
        width: '100%',
        height: '100%',
        backgroundColor: '#fff',
        justifyContent: 'center',
    },
    animatedView: {
        height: 60,
        backgroundColor: '#1f2afe',
        marginTop: 20,
        paddingLeft: 14,
        borderTopRightRadius: 20,
        borderBottomRightRadius: 20,
        flexDirection: 'row',
        alignItems: 'center',
    },
    image: {
        width: 32,
        height: 32,
        tintColor: 'white',
    },
    text: {
        color: '#fff',
        fontSize: 18,
        color: '#ffffffD0',
        marginLeft: 18,
        height: 32,
        lineHeight: 32,
    },
    dot: {
        width: 10,
        height: 10,
        backgroundColor: '#20f020',
        borderRadius: 5,
        marginLeft: 24,
    }
})
写回答

1回答

FE大公爵

2024-12-25

可以的可以的。非要提建议的话,在写循环渲染时,key的赋值尽量不要只用index,常规情况下没问题,但是涉及到列表增删就可能会有问题,key的组成中最好带上列表项的唯一标识字段。

 类似这样的

key={`${item.id}`}


0
0

RN从0到1系统精讲与小红书APP实战

30+小案例+2个实战项目,快人一步提升个职业竞争力

295 学习 · 211 问题

查看课程