我继承了以下组件,该组件与以前版本的react-native配合良好,在其他组件显示的按钮上显示不透明的滚动进度条。
最近,当我升级到react-native 0.62.2时,我收到一个请求添加
useNativeDriver
的错误。添加它并将其设置为“是”时,我收到一条错误消息“style property 'width' is not supported by native animated module
”。
将
useNativeDriver
设置为 false 时,我没有收到错误,但动画不起作用(至少在 Android 上不起作用。未在 iOS 上进行测试)。
关于如何修改代码以使其与最新版本的react-native一起工作有什么建议吗?
import React, { Component } from 'react';
import { Animated, Easing } from 'react-native';
import { connect } from 'react-redux';
class ProgressBar_Module extends Component {
constructor(props) {
super(props);
this.state = {
progress: 0
}
this.d_isMounted = false;
this.d_initialTime = 0;
this.d_animation_width = new Animated.Value(1);
this.d_animation_progressTime = 3000;
}
componentDidMount() {
this.d_initialTime = Date.now();
this.d_isMounted = true;
this.progressCount();
}
componentDidUpdate(prevProps) {
if(prevProps.timerStart < this.props.timerStart) {
this.setState({
animation_width: new Animated.Value(1),
animation_progressTime: 3000
});
this.progressCount(true)
}
}
componentWillUnmount() {
this.d_isMounted = false;
}
progressCount = (reset) => {
if( reset ) {
this.d_animation_width = new Animated.Value(1);
this.d_animation_progressTime = 3000;
}
Animated.timing(this.d_animation_width, {
toValue: 175,
duration: this.d_animation_progressTime,
easing: Easing.linear
}).start(() => {
if(this.props.timer && this.d_animation_width.__getValue() === 175) {
this.props.onPress();
}
})
}
render() {
return (
<Animated.View
style={[
{
position: 'absolute',
left: 0,
height: '150%',
width: 0,
zIndex: 1,
backgroundColor: 'black',
},
{ width: this.props.timer !== false ?
this.d_animation_width : 175 }
]}
onPress={this.props.onPress}
>
</Animated.View>
)
}
}
const mapStateToProps = state => {
return {
timer: state.get('ui').get('timer').get('timer'),
reset: state.get('ui').get('resetTimer').get('resetTimer'),
timerStart: state.get('ui').get('resetTimer').get('timerStart')
}
};
export const ProgressBar = connect(mapStateToProps)(ProgressBar_Module);
尝试这样做。
useNativeDriver: false
它对我有用。
不要对宽度进行动画处理,而是尝试使用transform和scaleX。 以下是反应本机转换的一些参考: https://reactnative.dev/docs/transforms
按照@YaNuSH的建议,我只需要更换
width: animatedValue
与:
transform: [{ scaleX: scaling }],
Animated.timing(this.d_animation_width, {
toValue: 175,
duration: this.d_animation_progressTime,
easing: Easing.linear
}).start(()
Animated.timing(this.d_animation_width, {
toValue: 175,
duration: this.d_animation_progressTime,
easing: Easing.linear,
useNativeDriver: true
}).start(()
return (
<Animated.View
style={[{
position: 'absolute',
left: 0,
height: '150%',
width: 0,
zIndex: 1,
backgroundColor: 'black',
},
{
width: this.props.timer !== false ?
this.d_animation_width : 175
}]}
onPress={this.props.onPress}
>
</Animated.View>
)
const scaling = this.props.timer !== false ? this.d_animation_width : 175;
return (
<Animated.View
style={[
{
position: 'absolute',
left: 0,
height: '150%',
width: 2,
zIndex: 1,
backgroundColor: 'black',
},
{
transform: [
{
scaleX: scaling
},
],
},
]}
onPress={this.props.onPress}
>
</Animated.View>
)
Animated.timing(this.loadingValue.width, {
toValue: widthEnd,
duration: 400,
useNativeDriver: false //add this line into the library
}).start();
Animated.timing(this.loadingValue.borderRadius, {
toValue: borderRadiusEnd,
duration: 400,
useNativeDriver: false //add this line into the library
}).start();
Animated.timing(this.loadingValue.opacity, {
toValue: opacityEnd,
duration: 300,
useNativeDriver: false //add this line into the library
}).start();
仅此而已...祝您编码愉快...
import React, { useEffect, useRef } from "react";
import { View, Animated, Easing, StyleSheet } from "react-native";
import { useTheme } from "../../utils/theme";
const SkeletonLoader = () => {
const numberOfLines = 15;
const theme = useTheme(); // Fetch theme from the custom hook
// Generate an array of lines
const lines = Array.from({ length: numberOfLines }, (_, index) => index);
// Animated values for pulse and width animation
const pulseAnim1 = useRef(new Animated.Value(1)).current;
const scaleXAnim = useRef(new Animated.Value(0)).current; // Start with 0 scale
// Pulse animation for the loader
const startPulseAnimation = () => {
Animated.loop(
Animated.sequence([
Animated.timing(pulseAnim1, {
toValue: 1.05,
duration: 700,
easing: Easing.inOut(Easing.ease),
useNativeDriver: true, // Native driver works for scale
}),
Animated.timing(pulseAnim1, {
toValue: 1,
duration: 700,
easing: Easing.inOut(Easing.ease),
useNativeDriver: true,
}),
])
).start();
};
// Line scaleX animation to simulate left-to-right growing effect
const startScaleXAnimation = () => {
Animated.timing(scaleXAnim, {
toValue: 1, // Expand scaleX to 1 (100%)
duration: 1200, // Time for the complete animation
easing: Easing.linear, // Linear motion for smooth animation
useNativeDriver: true, // Native driver can be used for scale
}).start(); // No loop, so it stops after one iteration
};
useEffect(() => {
startPulseAnimation();
startScaleXAnimation(); // Start the scaleX-growing animation
}, []);