javascript - React 原生动画进度条
问题描述
我正在尝试为我的 react-native 项目构建一个进度条它应该是一个可以在很多地方使用的通用组件。请看我的代码:
进度条 tsx:
import React, { useEffect } from 'react'
import { Animated, StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
interface Props {
total: number
progress: number
color?: string
backgroundColor?: string
height?: number
style?: StyleProp<ViewStyle>
animDelay?: number
animDuration?: number
testID?: string
}
const ProgressBar = ({
color,
backgroundColor,
style,
height,
animDelay,
animDuration,
total,
progress,
testID = 'progress-bar',
}: Props): JSX.Element => {
const minWidthValue = 5.4
const percentage = total && progress ? Math.min(progress, total) / total : 0
const minDisplayWidth =
percentage > 0 && percentage < minWidthValue ? minWidthValue : percentage
const barWidth = `${Math.max(minDisplayWidth, Math.floor(percentage * 100))}%`
useEffect(() => {
const animationValue = new Animated.Value(0)
Animated.timing(animationValue, {
toValue: progress,
delay: animDelay,
duration: animDuration,
useNativeDriver: true,
}).start();
}, []);
return (
<View
testID={testID}
style={[
styles.container,
height ? { height } : undefined,
backgroundColor ? { backgroundColor } : undefined,
style,
]}>
<Animated.View
style={[
styles.bar,
{
backgroundColor: color,
width: barWidth,
},
]}
/>
</View>
)
}
export default ProgressBar
const BORDER_RADIUS = 15
const styles = StyleSheet.create({
bar: {
borderRadius: BORDER_RADIUS,
height: '100%',
},
container: {
borderRadius: BORDER_RADIUS,
flexDirection: 'row',
height: 30,
overflow: 'hidden',
width: '100%',
},
})
还有用法的例子,在 home.tsx 上说:
<ProgressBarWrapper total={100} progress={50} testID='test-id-test-1' />
所以会发生什么,总长度(100%),我希望动画从 0 移动到 50 开始时,当这个组件加载时
使用上面的代码,我只得到一个静态栏,根本不动。有人能指出我做错了什么吗?示例代码会很有帮助 干杯
编辑:
我已经更新了代码
useNativeDriver
并interpolation
在此处使用“clamp”来避免振荡
但是,动画仍然没有移动/工作,想知道对此有何建议。谢谢
const ProgressBarInternal = ({
color,
backgroundColor,
style,
height,
animDelay,
animDuration,
total,
progress,
testID = 'progress-bar',
borderRadius,
containerHeight,
onAnimationDidEnd,
}: Props): JSX.Element => {
const minWidthValue = 5.4
const percentage = total && progress ? Math.min(progress, total) / total : 0
const minDisplayWidth =
percentage > 0 && percentage < minWidthValue ? minWidthValue : percentage
const progressingBarWidthPercentage = `${Math.max(minDisplayWidth, Math.floor(percentage * 100))}%`
const animatingProgressBar = useRef(new Animated.Value(0))
useEffect(() => {
Animated.timing(animatingProgressBar.current, {
toValue: 0,
delay: animDelay,
duration: animDuration,
useNativeDriver: true,
}).start()
}, []
);
return (
<View
testID={testID}
style={...}>
<Animated.View
style={[
styles.bar,
{ borderRadius: borderRadius },
{
backgroundColor: color,
width: progressingBarWidthPercentage,
},
{
transform: [
{
translateX: animatingProgressBar.current.interpolate({
inputRange: [1, 100],
outputRange: ["0%", "100%"],
extrapolate: "clamp"
}),
},
],
},
]}
/>
</View>
)
}
解决方案
当 useNativeDriver 设置为 true 时,我遇到了类似的行为。
将 useNativeDriver 更改为 false 可能会解决您的问题
这也是我如何实现动画宽度的示例:
const barWidth = useRef(new Animated.Value(0)).current;
const progressPercent = barWidth.interpolate({
inputRange: [0, 100],
outputRange: ["0%", `100%`],
});
useEffect(() => {
animatedController.setValue(0)
Animated.timing(barWidth, {
duration: 5000,
toValue: 100,
useNativeDriver: false
}).start();
}, [])
return (
<View style={...}>
<Animated.View
style={[
styles.bar,
{
backgroundColor: color,
width: progressPercent,
}
]}
/>
</View>
)
推荐阅读
- typescript - 算术运算的左侧必须是数组 reduce 上的“any”类型
- node.js - 使用 Node.js 客户端从 localhost 连接到 Bigtable 模拟器
- php - 从关系调用时没有出现新创建的记录
- oracle - Web 逻辑 - 托管服务器 - MaxPostSizeExceededException
- java - 使用自定义类作为键的 Java HashSet:“contains()”函数总是返回 false
- ios - 应用程序终止或在后台时在 IOS 设备上进行实时位置跟踪
- python - 如何使用 Anaconda 提示符安装 Rasa NLU
- azure - 如何获取 azure blob 的复制状态
- java - 在 JTextPane 中转换为大写或小写时,文本样式和格式正在发生变化
- mysql - 从 MYSQL 中删除超过 X 天的数据,Unix 时间以毫秒为单位