我想实现一个动画的可折叠列表/抽屉/下拉菜单/可折叠卡片。动画应具有高性能,如下所示:
n3h0vuf21#
经过大量的搜索,我可以找到许多库。但我想实现它没有任何库。而且,一些教程显示如何建立一个,但他们没有表现。最后,这是我如何实现它的。完整的零食代码如下:https://snack.expo.dev/@vipulchandra04/a85348我在state中存储了isOpen(无论菜单是打开还是关闭)。然后在按下按钮时改变状态。我在React-Native中使用LayoutAnimation API来动画打开和关闭列表。LayoutAnimation在本机运行动画,因此它是高性能的。
state
isOpen
React-Native
LayoutAnimation
const Accordion = ({ title, children }) => { const [isOpen, setIsOpen] = useState(false); const toggleOpen = () => { setIsOpen(value => !value); LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); } return ( <> <TouchableOpacity onPress={toggleOpen} activeOpacity={0.6}> {title} </TouchableOpacity> <View style={[styles.list, !isOpen ? styles.hidden : undefined]}> {children} </View> </> ); }; const styles = StyleSheet.create({ hidden: { height: 0, }, list: { overflow: 'hidden' }, });
z3yyvxxp2#
这样,它将修复Vipul演示的错误:如果按 accordion 太快,孩子不透明度下降到0。并添加动画图标
import { Animated, LayoutAnimation, Platform, StyleProp, StyleSheet, UIManager, View, ViewStyle, } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons; if ( Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental ) { UIManager.setLayoutAnimationEnabledExperimental(true); } const toggleAnimation = duration => { return { duration: duration, update: { property: LayoutAnimation.Properties.scaleXY, type: LayoutAnimation.Types.easeInEaseOut, }, delete: { property: LayoutAnimation.Properties.opacity, type: LayoutAnimation.Types.easeInEaseOut, }, }; }; interface IAccordion { title?: JSX.Element | JSX.Element[]; children?: JSX.Element | JSX.Element[]; style?: StyleProp<ViewStyle> | undefined; } const Accordion = ({title, children, style}: IAccordion) => { const [isOpen, setIsOpen] = useState(false); const animationController = useRef(new Animated.Value(0)).current; const arrowTransform = animationController.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '90deg'], }); const onToggle = () => { setIsOpen(prevState => !prevState); const duration = 300; const config = { duration: duration, toValue: isOpen ? 0 : 1, useNativeDriver: true, }; Animated.timing(animationController, config).start(); LayoutAnimation.configureNext(toggleAnimation(duration)); }; return ( <View style={style ? style : styles.accordion}> <TouchableOpacity onPress={onToggle} style={styles.heading}> {title} <Animated.View style={{transform: [{rotateZ: arrowTransform}]}}> <Ionicons name={'chevron-forward-outline'} size={18} /> </Animated.View> </TouchableOpacity> <View style={[styles.list, !isOpen ? styles.hidden : undefined]}> {children} </View> </View> ); }; export default Accordion;
2条答案
按热度按时间n3h0vuf21#
经过大量的搜索,我可以找到许多库。但我想实现它没有任何库。而且,一些教程显示如何建立一个,但他们没有表现。
最后,这是我如何实现它的。完整的零食代码如下:https://snack.expo.dev/@vipulchandra04/a85348
我在
state
中存储了isOpen
(无论菜单是打开还是关闭)。然后在按下按钮时改变状态。我在React-Native
中使用LayoutAnimation
API来动画打开和关闭列表。LayoutAnimation
在本机运行动画,因此它是高性能的。z3yyvxxp2#
这样,它将修复Vipul演示的错误:如果按 accordion 太快,孩子不透明度下降到0。并添加动画图标