gpt4 book ai didi

typescript - 如何在使用 Animated.View 的 native react 中为扩展/折叠文本预览设置动画

转载 作者:行者123 更新时间:2023-12-04 00:56:47 26 4
gpt4 key购买 nike

我正在创建一个默认为 2 行的文本组件,如果用户点击它,它将扩展到全长,如果用户再次点击它,它将折叠回 2 行。

到目前为止,我的返回函数中有这样的东西:

<TouchableWithoutFeedback
onPress={() => {
toggleExpansion();
}}
>
<Animated.View style={[{ height: animationHeight }]}>
<Text
style={styles.textStyle}
onLayout={event => setHeight(event.nativeEvent.layout.height)}
numberOfLines={numberOfLines}
>
{longText}
</Text>
</Animated.View>
</TouchableWithoutFeedback>

我的状态变量和 toggleExpansion 函数如下所示:
const [expanded, setExpanded] = useState(false);
const [height, setHeight] = useState(0);
const [numberOfLines, setNumberOfLines] = useState();

const toggleExpansion = () => {
setExpanded(!expanded);
if (expanded) {
setNumberOfLines(undefined);
} else {
setNumberOfLines(2);
}
};

到目前为止,这适用于展开和折叠,但我不确定如何设置 Animated.timing 函数来为其设置动画。我试过这样的事情:
const animationHeight = useRef(new Animated.Value(0)).current;

useEffect(() => {
Animated.timing(animationHeight, {
duration: 1000,
toValue: height,
easing: Easing.linear
}).start();
}, [height]);

但它并没有完全奏效。它根本不显示文本,当我尝试将新的 Animated.Value 初始化为大于 2 行高度(如 50)的数字时,无论我展开和折叠多少次,高度总是被截断为 16 .动画展开和折叠文本的最佳方法是什么?

最佳答案

我需要为动态高度组件解决这个问题,文本可以被解析 HTML,所以我们考虑了时髦的格式,比如额外的行。这将使用嵌入的 HTML 扩展 View 。如果你只是想控制文本布局,你可以通过改变文本 Prop 的状态来重新渲染组件。删除或更改渐变的颜色以匹配您的背景。
该组件使用“onLayout”监听器渲染全文 View 并获取高度,初始 View 容器设置为静态高度,如果渲染 TextView 的全高大于初始高度,则“读取显示更多”按钮,并为切换设置全高度值。
另外,如果有人对使用的 Spring 动画感到好奇,这里有一个很好的资源:https://medium.com/kaliberinteractive/how-i-transitioned-from-ease-to-spring-animations-5a09eeca0325
https://reactnative.dev/docs/animated#spring

import React, { useEffect, useState, useRef } from 'react';
import {
Animated,
StyleSheet,
Text,
TouchableWithoutFeedback,
View,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';

const MoreText = (props) => {
// const [text, setText] = useState('');
const startingHeight = 160;
const [expander, setExpander] = useState(false);
const [expanded, setExpanded] = useState(false);
const [fullHeight, setFullHeight] = useState(startingHeight);
const animatedHeight = useRef(new Animated.Value(startingHeight)).current;

useEffect(() => {
// expanded?setText(props.text): setText(props.text.substring(0, 40));
Animated.spring(animatedHeight, {
friction: 100,
toValue: expanded?fullHeight:startingHeight,
useNativeDriver: false
}).start();
}, [expanded]);

const onTextLayout = (e) => {
let {x, y, width, height} = e.nativeEvent.layout;
height = Math.floor(height) + 40;
if(height > startingHeight ){
setFullHeight(height);
setExpander(true);
}
};

return (
<View style={styles.container}>
<Animated.View style={[styles.viewPort, { height: animatedHeight }]}>
<View style={styles.textBox} onLayout={(e) => {onTextLayout(e)}}>
<Text style={styles.text}>{props.text}</Text>
</View>
</Animated.View>

{expander &&
<React.Fragment>
<LinearGradient
colors={[
'rgba(22, 22, 22,0.0)', // Change this gradient to match BG
'rgba(22, 22, 22,0.7)',
'rgba(22, 22, 22,0.9)',
]}
style={styles.gradient}/>
<TouchableWithoutFeedback onPress={() => {setExpanded(!expanded)}}>
<Text style={styles.readBtn}>{expanded?'Read Less':'Read More'}</Text>
</TouchableWithoutFeedback>
</React.Fragment>
}
</View>

);
}

const styles = StyleSheet.create({
absolute: {
position: "absolute",
height: 60,
left: 0,
bottom: 20,
right: 0
},
container: {
flex: 1,
},
viewPort: {
flex: 1,
overflow: 'hidden',
top: 12,
marginBottom: 20,
},
textBox: {
flex: 1,
position: 'absolute',
},
text: {
color: '#fff',
alignSelf: 'flex-start',
textAlign: 'justify',
fontSize: 14,
fontFamily: 'Avenir',
},
gradient:{
backgroundColor:'transparent', // required for gradient
height: 40,
width: '100%',
position:'absolute',
bottom: 20
},
readBtn: {
flex: 1,
color: 'blue',
alignSelf: 'flex-end',
},
});

export default MoreText;

关于typescript - 如何在使用 Animated.View 的 native react 中为扩展/折叠文本预览设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61809670/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com