如何在Android上动画化视图的背景颜色变化?

例如:

我有一个红色背景色的视图。视图的背景颜色变为蓝色。我怎样才能在颜色之间平滑过渡呢?

如果视图不能做到这一点,那么另一种选择是受欢迎的。


当前回答

基于ademar111190的答案,我创建了这个方法,它将在任意两种颜色之间脉冲视图的背景颜色:

private void animateBackground(View view, int colorFrom, int colorTo, int duration) {


    ObjectAnimator objectAnimator = ObjectAnimator.ofObject(view, "backgroundColor", new ArgbEvaluator(), colorFrom, colorTo);
    objectAnimator.setDuration(duration);
    //objectAnimator.setRepeatCount(Animation.INFINITE);
    objectAnimator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            // Call this method again, but with the two colors switched around.
            animateBackground(view, colorTo, colorFrom, duration);
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });
    objectAnimator.start();
}

其他回答

基于ademar111190的答案,我创建了这个方法,它将在任意两种颜色之间脉冲视图的背景颜色:

private void animateBackground(View view, int colorFrom, int colorTo, int duration) {


    ObjectAnimator objectAnimator = ObjectAnimator.ofObject(view, "backgroundColor", new ArgbEvaluator(), colorFrom, colorTo);
    objectAnimator.setDuration(duration);
    //objectAnimator.setRepeatCount(Animation.INFINITE);
    objectAnimator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            // Call this method again, but with the two colors switched around.
            animateBackground(view, colorTo, colorFrom, duration);
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });
    objectAnimator.start();
}

你可以创建一个对象动画器。例如,我有一个targetView,我想改变你的背景颜色:

int colorFrom = Color.RED;
int colorTo = Color.GREEN;
int duration = 1000;
ObjectAnimator.ofObject(targetView, "backgroundColor", new ArgbEvaluator(), colorFrom, colorTo)
    .setDuration(duration)
    .start();

我最终想出了一个(非常好的)解决这个问题的方法!

你可以使用TransitionDrawable来完成这个任务。例如,在可绘制文件夹中的XML文件中,你可以这样写:

<?xml version="1.0" encoding="UTF-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- The drawables used here can be solid colors, gradients, shapes, images, etc. -->
    <item android:drawable="@drawable/original_state" />
    <item android:drawable="@drawable/new_state" />
</transition>

然后,在实际视图的XML中,你会在android:background属性中引用这个TransitionDrawable。

在这一点上,你可以在你的代码中执行以下命令来启动转换:

TransitionDrawable transition = (TransitionDrawable) viewObj.getBackground();
transition.startTransition(transitionTime);

或者反向运行转换,调用:

transition.reverseTransition(transitionTime);

请参阅Roman使用属性动画API的另一个解决方案的答案,在这个答案最初发布时还不可用。

实现这一点的另一种简单方法是使用AlphaAnimation执行渐隐。

将视图设置为ViewGroup 在索引0处添加一个子视图,使用match_parent布局维度 给你的孩子与容器相同的背景 更改容器的背景为目标颜色 使用AlphaAnimation淡出子动画。 当动画完成时删除子动画(使用AnimationListener)

最好的方法是使用ValueAnimator和ColorUtils.blendARGB

 ValueAnimator valueAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
 valueAnimator.setDuration(325);
 valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {

              float fractionAnim = (float) valueAnimator.getAnimatedValue();

              view.setBackgroundColor(ColorUtils.blendARGB(Color.parseColor("#FFFFFF")
                                    , Color.parseColor("#000000")
                                    , fractionAnim));
        }
});
valueAnimator.start();