LayoutAnimationController可以只对指定的View进行动画吗?

4
有没有可能以某种方式覆盖Android的LayoutAnimationController,使得我在ViewGroup内指定的特定子View才会执行动画?我的目标是基于Activity的当前状态选择任意一组子视图,并同时使用相同的动画进行动画处理,然后在稍后的时间选择不同的任意子视图并做同样的事情。我想一直这样做,直到Activity运行结束。
到目前为止,我已经查看并放弃了几个选项:
1.调用startAnimation(Animation)来逐个地启动特定的子视图,但是不能保证它们都会在完全相同的时间开始和结束,特别是如果任意集合中的视图数量很大。
2.覆盖LayoutAnimationController.getAnimationForView()似乎是最简单的方法,但该方法是final的,无法被覆盖。
我已经思考了一段时间,觉得可以尝试一下Stack Overflow。
3个回答

7

我无法找到更改Android的LayoutAnimationController的方法,但是我想出了一个简单的解决方案来实现我的目标。我创建了一个View子类,可以有选择地忽略运行动画的调用。

public class AnimationAverseView extends View {

    private boolean mIsAnimatable = true;

    public void setAnimatible(boolean isAnimatable) {
        if (!isAnimatable) {
            clearAnimation();
        }
        mIsAnimatable = isAnimatable;
    }

    @Override
    public void startAnimation(Animation animation) {
        if (mIsAnimatable) {
            super.startAnimation(animation);
        }
    }
}

我不担心其他可能与动画有关的方法,因为我只通过LayoutAnimationController来对View进行动画处理。


嘿,这个解决方案不起作用...请帮帮我,我已经设置了一些子项的mIsAnimatable,但仍然全部在动画。 - Shridutt Kothari
你是否尝试使用除了LayoutAnimationController之外的其他方法来为这些视图添加动画效果?上述代码未处理其他可用于视图的动画相关方法。 - happydude
如果您有一些视图不想受到影响,这些视图是从XML中膨胀的,并且位于RelativeLayout等ViewGroup中,则可以创建AnimationAverseRelativeLayout并在布局中使用它。这对我在listView设置中非常有帮助,因为我需要一些单元格进行动画处理,而其他单元格则不需要动画处理。 - havchr
@havchr,你在ListView中使用AnimationAverseLayout时需要做其他的事情吗?我试图在LinearLayout中设置我的列表视图头部来实现这个方法,但似乎不起作用。 - GrouchyPanda
@ChrisM,你创建了AnimationAverseLinearLayout类并使用它来替代linearLayout吗?如果是的话,我不确定哪里出了问题。 - havchr
@ChrisM 我不确定这是否是你的问题,但是一个“动画厌恶”的ViewGroup并不能阻止其任何子视图在直接调用startAnimation()时进行动画。在这种情况下,您需要告诉每个子视图单独不要进行动画。 - happydude

1
我看到这个问题是7年6个月前提出的,但今天我遇到了它,创建自定义子视图对我来说有些麻烦。我发现使用自定义外部布局似乎可以解决问题,您需要覆盖attachLayoutAnimationParameters方法。该方法针对每个作为布局动画一部分的子视图调用,并且在ViewGroup中实际触发布局动画时调用它。它将AnimationLayoutParams附加到子项上,从而使其动画化。因此,简单地说,如果您不将任何LayoutAnimation参数附加到子项上,则它将不是布局动画的一部分。
class CustomLayout @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {

    private val excludeForLayoutAnimation by lazy {
        listOfNotNull(findViewById(R.id.text), findViewById(R.id.fab))
    }

    override fun attachLayoutAnimationParameters(
        child: View?,
        params: ViewGroup.LayoutParams?,
        index: Int,
        count: Int
    ) {
        if (child !in excludeForLayoutAnimation) {
            super.attachLayoutAnimationParameters(child, params, index, count)
        }
    }

}

如果您现在只是在外部自定义视图上调用此函数,它将排除您指定的子元素:
customView?.apply {
    layoutAnimation = AnimationUtils.loadLayoutAnimation(
        context,
        R.anim.layout_animation_fade_in
    )
    scheduleLayoutAnimation() // or maybe startLayoutAnimation()
}

0

我无法在已接受的答案中添加评论,因此在此处添加一些额外信息。happydude(2月17日)的评论对我也是正确的。我的ListView标题的最外层视图是FrameLayout,我需要覆盖setAnimation()方法以防止标题与列表的其余部分一起动画。因此,您应该检查哪些其他动画方法可能需要覆盖。


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