同时将一个动画应用于多个视图

25

我想同时旋转一些视图,它们都使用相同的旋转规格。问题是,由于某种原因,第二个元素的旋转效果不同。显然,这与动画对象在这两行代码之间实际上改变了状态有关。显然,我可以创建一个单独的动画对象并应用它,但我觉得有一种更简单的方法(我大约有15个视图)

仅正确旋转第一个视图:

Animation rotateAnim = AnimationUtils.loadAnimation(this, R.anim.rotationtoportrait);
target.startAnimation(rotateAnim);
lightBtn.startAnimation(rotateAnim);

旋转正确

Animation rotateAnim = AnimationUtils.loadAnimation(this, R.anim.rotationtoportrait);
Animation rotateAnim2 = AnimationUtils.loadAnimation(this, R.anim.rotationtoportrait);
target.startAnimation(rotateAnim);
lightBtn.startAnimation(rotateAnim2);

XML:

<?xml version="1.0" encoding="utf-8"?>
<rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="-90"
    android:toDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="500" android:fillAfter="true">

有人有任何想法吗?


1
尝试使用新的动画 API(向后兼容请使用 NineOldAndroids)。我还建议观看这个视频:http://www.youtube.com/watch?v=_UWXqFBF86U - Leandros
喜欢这个视频!但是有什么新的API,就我所知道的,这就是视频中那个人做的事情吗?(至少在结尾部分) - Jameo
1
视频链接错误,抱歉。 ;) http://www.youtube.com/watch?v=3UbJhmkeSig - Leandros
谢谢提供视频。新API肯定更强大,但我认为无论如何,您需要创建动画对象与要旋转的对象之间的1对1关系。除非您可以使用anim.setTarget(v1)anim.setTarget(v2)设置多个目标视图? - Jameo
3个回答

10

就像这样做:

ObjectAnimator anim = ObjectAnimator.ofFloat(view, "y", 100f);
arrayListObjectAnimators.add(anim);

ObjectAnimator anim1 = ObjectAnimator.ofFloat(view, "x", 0f);
arrayListObjectAnimators.add(anim1);

ObjectAnimator[] objectAnimators = arrayListObjectAnimators.toArray(new ObjectAnimator[arrayListObjectAnimators.size()]);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(objectAnimators);
animSetXY.duration(1000);
animSetXY.start();

10
这并没有回答问题。如果我没理解错的话,你正试图将两个动画应用于同一个视图。原贴想要将相同的动画应用于两个视图。 - Daniel Wilson
.duration(1000) should be .setDuration(1000) - Vasia Zaretskyi

5

我猜这可能是不可能的,因此我创建了一个辅助方法,将相同的动画应用于一系列视图:

public void doRotations(ArrayList<View> views, int start, int end, int xprop, float xscale, int yprop, float yscale, int duration, Boolean fillAfter){

    for(int i = 0; i < views.size(); i++){
        RotateAnimation temp = new RotateAnimation(start, end, xprop, xscale, yprop, yscale);
        temp.setDuration(duration);
        temp.setFillAfter(fillAfter);
        views.get(i).startAnimation(temp);
    }
}

这绝对是一个黑客攻击,但我猜现在我能做的就只有这些了。


这确实可以并行运行动画,但是如果你仔细观察,你会看到动画之间有轻微的延迟(毕竟你是按顺序触发动画的)。 - Mercury
2
@Mercury 如果您在主线程上执行此操作,直到完成之前不会绘制任何内容。您的计算会阻塞主线程。没有动画会立即开始。当您完成后,下一个布局传递将实际启动动画,并且我相信它们应该同时开始。 - Stan

0

我能够在 Kotlin 中通过编程方式创建一个 AnimatorSet 来实现这一点。
1. 创建一个要执行动画的视图的 ArrayList

 var viewList = arrayListOf(view1,view2,view3)

2. 遍历ArrayList并创建一个不断增长的AnimatorSet

var ix = 0
var anim = AnimatorSet()
var viewList = arrayListOf(view1,view2,view3)
        viewList.forEach{
        // Initiate the animator set with one ObjectAnimator
            if(ix == 0){
                anim = AnimatorSet().apply {
                    play(ObjectAnimator.ofFloat(it, "rotation", 0F, 360F))
                }
            }
        // Add one ObjectAnimator at a time to the growing AnimatorSet
            else{
                var currentAnim = ObjectAnimator.ofFloat(it,"rotation",0F,360F)
                anim = AnimatorSet().apply {
                    play(anim).with(currentAnim)
                }
            }
            ix++
        }

3. 开始动画

button.setOnClickListener {
            AnimatorSet().apply {
                play(anim)
                start()
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接