Reactjs 如何通过更改React Native中的状态从一个图像转换到另一个图像
我有两个图像,它们之间差别不大,每个图像对应一个特定的状态。当我改变状态时,我需要从一个平滑地过渡到另一个,这样效果感觉就像只有两个图像中不同的部分经历了动画,图像的其余部分保持原样。 我希望它能够工作,这样当我在stateChange上渲染第二个图像时,只有第二个图像中的棒状部分会淡入,其余部分保持静止 我认为这可以在不使用任何动画库(如react transition group)的情况下实现,可能是通过使用react中的一些生命周期方法,当然还有AnimatedAPI。我面临的主要问题是,当我更新状态时,我无法控制先前渲染的图像。我不知何故希望先前渲染的图像保持不变,直到新渲染的组件出现并执行其动画。这就是我试图做的。我有一个ImageLoader组件,它在渲染图像的同时为图像提供淡入动画Reactjs 如何通过更改React Native中的状态从一个图像转换到另一个图像,reactjs,react-native,react-native-android,Reactjs,React Native,React Native Android,我有两个图像,它们之间差别不大,每个图像对应一个特定的状态。当我改变状态时,我需要从一个平滑地过渡到另一个,这样效果感觉就像只有两个图像中不同的部分经历了动画,图像的其余部分保持原样。 我希望它能够工作,这样当我在stateChange上渲染第二个图像时,只有第二个图像中的棒状部分会淡入,其余部分保持静止 我认为这可以在不使用任何动画库(如react transition group)的情况下实现,可能是通过使用react中的一些生命周期方法,当然还有AnimatedAPI。我面临的主要问题是
class ImageLoader extends React.Component {
constructor(){
super()
this.opacity= new Animated.Value(0)
}
componentDidUpdate(){
{this.onLoad()}
}
onLoad = () => {
this.opacity.setValue(0);
Animated.timing(this.opacity, {
toValue: 1,
duration: 500,
useNativeDriver: true,
}).start();
}
render() {
return (
<Animated.Image onLoad={this.onLoad}{...this.props}style={[
{opacity: this.opacity,}, this.props.style,
]}
/>
);
}
}
export default class App extends React.Component {
state={
no:1,
}
render() {
let Dun=()=>{return this.state.no==1?
<ImageLoader source={require('./assets/img1.PNG')}/>: <ImageLoader
source={require('./assets/img2.PNG')}/>
}
const calc=()=>{
this.setState((state)=>({no:Math.abs(state.no-1)}));
}
return (
<View style={styles.container}>
<View style={{height:100,marginLeft:50}}>
{Dun()}
<Button onPress={()=>{calc()}}> Press</Button>
</View>
</View>
);
}
}
您可以使用两个动画图像给人一个正在淡入另一个的印象。以下是基于您的示例的解决方案:
import React from 'react';
import { Animated, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import images from 'src/images';
const styles = StyleSheet.create({
image: {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0
}
});
class ImageSwitcher extends React.Component {
fadeInOpacity = new Animated.Value(0);
fadeOutOpacity = new Animated.Value(1);
state = {
prevSource: null
};
componentDidMount() {
this.onLoad();
}
componentDidUpdate() {
this.onLoad();
}
componentWillReceiveProps({ source: newSource }) {
const { source } = this.props;
if (newSource !== source) {
this.setState({ prevSource: source });
}
}
onLoad = () => {
this.fadeInOpacity.setValue(0);
this.fadeOutOpacity.setValue(1);
Animated.timing(this.fadeInOpacity, {
toValue: 1,
duration: 500,
useNativeDriver: true
}).start();
Animated.timing(this.fadeOutOpacity, {
toValue: 0,
duration: 500,
useNativeDriver: true
}).start();
};
render() {
const { prevSource } = this.state;
return (
<View
style={{
width: 200,
height: 200
}}
>
<Animated.Image {...this.props} style={[styles.image, { opacity: this.fadeInOpacity }]} resizeMode="cover" />
{prevSource && (
<Animated.Image {...this.props} style={[styles.image, { opacity: this.fadeOutOpacity }]} resizeMode="cover" source={prevSource} />
)}
</View>
);
}
}
export default class App extends React.Component {
state = {
source: images.first
};
handleToggle = () => this.setState(({ source }) => ({ source: source === images.first ? images.second : images.first }));
render() {
const { source } = this.state;
return (
<View style={{ flex: 1 }}>
<ImageSwitcher source={source} />
<TouchableOpacity onPress={this.handleToggle}>
<Text>Toggle Image</Text>
</TouchableOpacity>
</View>
);
}
}
谢谢。如果我有6张我想一张接一张地显示的图片,我可以用这个吗?为什么不呢。在上一个动画完成后,只需让它前进到下一个源。如果要立即开始下一个动画,则Animated.timing.startcallback将进行可选回调