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

Posted

技术标签:

【中文标题】同时将一个动画应用于多个视图【英文标题】:Apply one animation to multiple views at the same time 【发布时间】:2013-01-28 07:09:31 【问题描述】:

所以我想同时旋转几个视图,所有视图都使用相同的旋转规范。问题是由于某种原因,第二个元素的旋转作用不同。显然,这与动画对象在这两行代码之间实际改变状态有关。显然我可以创建一个单独的动画对象并应用它,但我觉得有一种更简单的方法(我有大约 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">

谁有想法?

【问题讨论】:

尝试使用新的动画 API(为了向后兼容使用 NineOldAndroids)。我也建议观看:youtube.com/watch?v=_UWXqFBF86U 喜欢这个视频!但是,据我所知,视频中的那个人做了什么新的 API?(至少在最后) 错误的视频,抱歉。 ;) youtube.com/watch?v=3UbJhmkeSig 感谢您的视频。新的 API 肯定更强大,但我认为无论哪种方式,您都需要创建动画对象与要旋转的对象的一对一关系。除非您可以使用 anim.setTarget(v1) anim.setTarget(v2) 设置多个目标视图? 【参考方案1】:

这样做:

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();

【讨论】:

这不能回答问题,如果我是正确的,您将 2 个动画应用于同一个视图。原帖想将相同的动画应用到 2 个视图 .duration(1000) 应该是.setDuration(1000)【参考方案2】:

所以我想这是不可能的,所以我创建了一个辅助方法来将相同的动画应用于视图列表:

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);
    

绝对是一个 hack,但我想这就是我现在能做的全部

【讨论】:

这确实是并行运行动画,但是如果你仔细观察,你可以看到动画之间有轻微的延迟(因为你毕竟是按顺序触发动画的)。 @Mercury 如果您在主线程上执行此操作,则在完成之前不会绘制任何内容。您的计算阻塞了主线程。没有动画会立即开始。完成后,下一个布局通道实际上会启动动画,我相信它们应该同时启动。【参考方案3】:

我可以在 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()
            

【讨论】:

以上是关于同时将一个动画应用于多个视图的主要内容,如果未能解决你的问题,请参考以下文章

单个动画 - 多个视图

如何在不同视图中同步多个动画

在动画呈现控制器视图的同时动画呈现控制器视图

如何在 tableview 中为图像设置动画以同时扩展和打开另一个视图控制器?

从视图模型 (WPF) 调用视图中的动画

iOS 使用动画块转换视图