【问题标题】:Reversing an Animation反转动画
【发布时间】:2010-11-08 02:14:58
【问题描述】:

我有一个 ImageView,当它被添加到布局时会产生动画效果。 当它被移除时,我想反转相同的动画。

有没有办法在不重新编码和反转参数的情况下在 android 中反转动画?

【问题讨论】:

标签: android animation


【解决方案1】:

不,很遗憾你不能用 Animation 对象做到这一点。 但是您可以使用将反转动画的插值器来模拟它:

package com.example.android;

import android.view.animation.Interpolator;

public class ReverseInterpolator implements Interpolator {
    @Override
    public float getInterpolation(float paramFloat) {
        return Math.abs(paramFloat -1f);
    }
}

然后你可以在你的动画上设置你的新插值器:

myAnimation.setInterpolator(new ReverseInterpolator());

【讨论】:

  • 我知道我迟到了。我试过这段代码它对我不起作用。动画结束后它只是回到开始位置而没有任何动画。如何反向制作动画?
  • 您好,我在发布之前尝试了代码,它在一个简单的测试中对我有用。请发布一些代码,显示您如何尝试应用插值器。
  • 在某些情况下这可能是一个解决方案:animation.setRepeatCount(Animation.INFINITE); animation.setRepeatMode(Animation.REVERSE);
  • 这可能只是return 1f - paramFloat;,因为您将[0..1] 映射到[1..0]
【解决方案2】:

如果您使用 Object 或 ValueAnimator 为视图设置动画,您可以简单地做

ValueAnimator myAnimator = new ValueAnimator();  
myAnimator.reverse()

可以在here找到文档。

【讨论】:

  • 这只是API级别+23
  • ValueAnimator 类是在 API 11 中引入的动画 API 中添加的。
【解决方案3】:

基于pcans 的想法,您可以反转任何插值器,而不仅仅是线性。

class ReverseInterpolator implements Interpolator{
    private final Interpolator delegate;

    public ReverseInterpolator(Interpolator delegate){
        this.delegate = delegate;
    }

    public ReverseInterpolator(){
        this(new LinearInterpolator());
    }

    @Override
    public float getInterpolation(float input) {
        return 1 - delegate.getInterpolation(input);
    }
}

用法

ReverseInterpolator reverseInterpolator = new ReverseInterpolator(new AccelerateInterpolator())
myAnimation.setInterpolator(reverseInterpolator);

【讨论】:

  • 这对我不起作用,直到我从 return 1 - delegate.getInterpolation(input); 更改为 return delegate.getInterpolation(1 - input);
  • 有趣。我想它适用于所有对称代表。
【解决方案4】:

我对 pcans 有类似的方法,但略有不同。它需要一个Interpolator,并且将有效地传递与使用传入的Interpolator 相同的值,然后在反向模式下使用。让您不必考虑 Android 中的 Animation.REVERSE 的错误实现。见代码here

public class ReverseInterpolator implements Interpolator {

    private final Interpolator mInterpolator;

    public ReverseInterpolator(Interpolator interpolator){
        mInterpolator = interpolator;
    }

    @Override
    public float getInterpolation(float input) {
        return mInterpolator.getInterpolation(reverseInput(input));
    }

    /**
     * Map value so 0-0.5 = 0-1 and 0.5-1 = 1-0
     */
    private float reverseInput(float input){        
        if(input <= 0.5)
            return input*2;
        else
            return Math.abs(input-1)*2;        
    }
}

【讨论】:

  • 这对我有用!来自@pcans 的解决方案 - 没有
【解决方案5】:

我想出的最简单的解决方案

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/linear_interpolator">
    <alpha
        android:duration="2000"
        android:fromAlpha="0.1"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:toAlpha="1.0">
    </alpha>
</set>

【讨论】:

  • android:repeatMode="reverse" 拯救了我的一天 :)
【解决方案6】:

您可以让代码记住原始位置和结束位置。并让您的代码在触发动画时动态获取这些值。

【讨论】:

    【解决方案7】:

    如果您使用来自 xml 的动画,那么一种简单的方法是制作与原始动画完全相同的反向动画。将Animation.AnimationListener添加到原始动画中,并在onAnimationEnd方法中启动反向动画。

    【讨论】:

      【解决方案8】:

      这对我有用

       ObjectAnimator anim = ObjectAnimator.ofFloat(imageViewUpb, "rotation", rotationAngle, rotationAngle + 180);
      
                  if (linearLayoutb.getVisibility()==GONE){
      
                      linearLayoutb.setVisibility(VISIBLE);
                      anim.setDuration(500);
                      anim.start();
                      rotationAngle += 180;
                      rotationAngle = rotationAngle%360;
              imageViewUpb.animate().rotation(rotationAngle).setDuration(500).start();
      
                  }else{
      
                      linearLayoutb.setVisibility(GONE);
                      anim.setDuration(500);
                      anim.start();
                      rotationAngle += 180;
                      rotationAngle = rotationAngle%180;
      imageViewUpDownb.animate().rotation(rotationAngle).setDuration(500).start();
      
                  }
      

      linearlayoutb 是 imageviewUpb 朝上时展开的视图

      制作int rotationAngle = 0; global parameter

      【讨论】:

        【解决方案9】:

        你需要使用RepeatCount和RepeatMode

        科特林

           var anim = TranslateAnimation(0, 100, 0, 100)
           anim.repeatCount = Animation.INFINITE // you cant 1,2,...
           anim.repeatMode = Animation.REVERSE // you can set REVERSE or RESTART
           anim.start()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-23
          • 2018-01-13
          • 2015-11-06
          相关资源
          最近更新 更多