Reactjs 如何通过更改React Native中的状态从一个图像转换到另一个图像

Reactjs 如何通过更改React Native中的状态从一个图像转换到另一个图像,reactjs,react-native,react-native-android,Reactjs,React Native,React Native Android,我有两个图像,它们之间差别不大,每个图像对应一个特定的状态。当我改变状态时,我需要从一个平滑地过渡到另一个,这样效果感觉就像只有两个图像中不同的部分经历了动画,图像的其余部分保持原样。 我希望它能够工作,这样当我在stateChange上渲染第二个图像时,只有第二个图像中的棒状部分会淡入,其余部分保持静止 我认为这可以在不使用任何动画库(如react transition group)的情况下实现,可能是通过使用react中的一些生命周期方法,当然还有AnimatedAPI。我面临的主要问题是

我有两个图像,它们之间差别不大,每个图像对应一个特定的状态。当我改变状态时,我需要从一个平滑地过渡到另一个,这样效果感觉就像只有两个图像中不同的部分经历了动画,图像的其余部分保持原样。

我希望它能够工作,这样当我在stateChange上渲染第二个图像时,只有第二个图像中的棒状部分会淡入,其余部分保持静止

我认为这可以在不使用任何动画库(如react transition group)的情况下实现,可能是通过使用react中的一些生命周期方法,当然还有AnimatedAPI。我面临的主要问题是,当我更新状态时,我无法控制先前渲染的图像。我不知何故希望先前渲染的图像保持不变,直到新渲染的组件出现并执行其动画。这就是我试图做的。我有一个ImageLoader组件,它在渲染图像的同时为图像提供淡入动画

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将进行可选回调