【问题标题】:Is it possible to assign a value (id) to animations in React Native?是否可以为 React Native 中的动画分配一个值(id)?
【发布时间】:2018-05-17 18:17:09
【问题描述】:

假设我的动画被迭代 20 次,但我不希望所有动画同时播放。我将如何触发一个值为1 的特定动画。如果我点击了1,那么除了1之外,其他19个不应该触发。

    export default class AnimateScreen extends React.PureComponent {
    constructor(props){

      super(props);

      this.forceUpdateHandler = this.forceUpdateHandler.bind(this);

      this.state = {
      dataSource: '',
      progress: new Animated.Value(0),
    };


    animate = (id) => {

          Animated.timing(this.state.progress, {
            toValue: 1,
            duration: 5000,
            easing: Easing.linear,
          }).start([id]); <!-- Here is my attempt in trying to animate that one specific animation. 


render(){
return(
    <FlatList
               data={this.state.dataSource}
               renderItem={({item}) => 
              <View>
               <View>
                 <Text>Work in progress</Text>
                 <View>
                 <TouchableHighlight
                 onPress={this.animate.bind(this, item.id)}>
                  <Animation
                  progress={this.state.progress}
                  source={require('../tools/animations/heart_icon.json')}
                  />
        </TouchableHighlight>

                   <Text> Hello</Text>

                 </View>

               </View>


               </View>
             }
             keyExtractor={(item, index) => index.toString()}
          />
        );
        }
    }

我试过了,仍然触发了所有动画。有没有办法专门触发它们?

数据源:

"dataSource":[{"id":"10","images":"Emerson live in the sunshine swim in the sea drink the wild air.jpg","note":"Hello","tag":"sunshine"}


    componentDidUpdate(prevProps, prevState) {
  if (!prevState.dataSource) {

      return fetch(`https://www.website.com/React/json-data.php` , {
       method: 'POST',
       headers: {
         'Accept': 'application/json',
         'Content-Type': 'application/json',
       }

      })
        .then((response) => response.json())
        .then((responseJson) => {
          this.setState({
            dataSource: responseJson,
            },function() {
              // In this block you can do something with new state.
            });
        })
        .catch((error) => {
          console.error(error);
        });
    }
  }

【问题讨论】:

  • 看起来 this.state.progress 可能会传递给您的所有项目。我建议将进度/动画部分移动到动画组件中,或者在每个项目上设置一个进度键并让动画调整该值。
  • 我不确定你的第一个建议是什么意思,但第二个建议是不是这样的:progress={this.state.progress(this, item.id)}? @MattAft
  • 不,一个例子是一旦你得到项目,你将进度键映射到它们items = items.map(item =&gt; ({ ...item, progress: 0 }) 所以每个项目都会有它自己的进度设置为 0 然后而不是使用 this.state.progress,您将使用每个项目唯一的 item.progress。
  • @MattAft 这似乎是一种有趣的方法,一个问题,我将把代码的 sn-p 放在哪里?抱歉,我刚接触 React Native。
  • 不用担心,您能发布更多代码吗?我会设置它并将其作为答案发布在下面

标签: reactjs react-native react-animated lottie react-animations


【解决方案1】:

基本上,您可以将进度键添加到数据源中的每个项目,并将动画值设置为 0,然后单击您将为该项目的进度设置动画。大致应该是这样的:

export default class AnimateScreen extends React.PureComponent {
  constructor(props){

    super(props);

    this.forceUpdateHandler = this.forceUpdateHandler.bind(this);

    this.state = {
      dataSource: [],
      progress: new Animated.Value(0),
    };

    componentDidUpdate(prevProps, prevState) {
      if (!prevState.dataSource) {

        return fetch(`https://www.website.com/React/json-data.php` , {
          method: 'POST',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
          }

        })
        .then((response) => response.json())
        .then((responseJson) => {
          this.setState({
            dataSource: responseJson.map(item => ({ ...item, progress: new Animated.Value(0) })), // Add progress key
          },function() {
            // In this block you can do something with new state.
          });
        })
        .catch((error) => {
          console.error(error);
        });
      }
    }


    animate = (item) => {
      Animated.timing(item.progress, {
        toValue: 1,
        duration: 5000,
        easing: Easing.linear,
      }).start(); <!-- Here is my attempt in trying to animate that one specific animation. 


      render(){
        return(
          <FlatList
            data={this.state.dataSource}
            renderItem={({item}) => 
            <View>
              <View>
                <Text>Work in progress</Text>
                <View>
                  <TouchableHighlight
                    onPress={() => this.animate(item)}>
                    <Animation
                      progress={item.progress}
                      source={require('../tools/animations/heart_icon.json')}
                    />
                  </TouchableHighlight>

                  <Text> Hello</Text>

                </View>

              </View>


            </View>
          }
          keyExtractor={(item, index) => index.toString()}
        />
      );
    }
  }

【讨论】:

  • 我的数据源基本上是一个 JSON 文件,我将在上面的代码中进行更新。另外,... 中的item 是什么意思?
  • 好的,我更新了我的答案以包括您的获取,这些点是 es6 传播。它基本上是从 item 中获取所有内容并创建一个包含进度键的新对象:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 这很好,我还没有测试代码,因为我必须重新排列一些代码。由于我将 dataSource 用于其余的 JSON 数据,因此我将其重命名为:id: responseJson.map(item =&gt; ({ ...item, progress: new Animated.Value(0) })) 希望有效
  • 嗯不知道为什么需要重命名它,其他一切都还在。它实际上只是为每个项目添加进度
  • 啊,你是对的。运行代码时也出现错误:undefined is not an object (evaluating 'singleValue.stopTracking')
猜你喜欢
  • 2018-07-26
  • 2017-07-22
  • 1970-01-01
  • 2013-06-26
  • 2013-05-08
  • 2017-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多