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

例如:

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

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


当前回答

罗曼米诺克回答在kotlin和作为扩展函数

fun View.colorTransition(@ColorRes startColor: Int, @ColorRes endColor: Int, duration: Long = 250L){
    val colorFrom = ContextCompat.getColor(context, startColor)
    val colorTo =  ContextCompat.getColor(context, endColor)
    val colorAnimation: ValueAnimator = ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo)
    colorAnimation.duration = duration

    colorAnimation.addUpdateListener {
        if (it.animatedValue is Int) {
            val color=it.animatedValue as Int
            setBackgroundColor(color)
        }
    }
    colorAnimation.start()
}

如果你想改变当前的背景色到新的颜色,那么你可以使用这个

fun View.colorTransition(@ColorRes endColor: Int, duration: Long = 250L){
    var colorFrom = Color.TRANSPARENT
    if (background is ColorDrawable)
        colorFrom = (background as ColorDrawable).color

    val colorTo =  ContextCompat.getcolor(context, endColor)
    val colorAnimation: ValueAnimator = ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo)
    colorAnimation.duration = duration

    colorAnimation.addUpdateListener {
        if (it.animatedValue is Int) {
            val color=it.animatedValue as Int
            setBackgroundColor(color)
        }
    }
    colorAnimation.start()
}

使用

myView.colorTransition(R.color.bg_color)

其他回答

这是我在Base Activity中用来改变背景的方法。我使用在代码中生成的GradientDrawables,但可以适应。

    protected void setPageBackground(View root, int type){
        if (root!=null) {
            Drawable currentBG = root.getBackground();
            //add your own logic here to determine the newBG 
            Drawable newBG = Utils.createGradientDrawable(type); 
            if (currentBG==null) {
                if(Build.VERSION.SDK_INT<Build.VERSION_CODES.JELLY_BEAN){
                    root.setBackgroundDrawable(newBG);
                }else{
                    root.setBackground(newBG);
                }
            }else{
                TransitionDrawable transitionDrawable = new TransitionDrawable(new Drawable[]{currentBG, newBG});
                transitionDrawable.setCrossFadeEnabled(true);
                if(Build.VERSION.SDK_INT<Build.VERSION_CODES.JELLY_BEAN){
                     root.setBackgroundDrawable(transitionDrawable);
                }else{
                    root.setBackground(transitionDrawable);
                }
                transitionDrawable.startTransition(400);
            }
        }
    }

更新:如果有人遇到同样的问题,我发现,出于某种原因,在Android <4.3使用setCrossFadeEnabled(true)导致一个不受欢迎的白色效果,所以我不得不切换到一个纯色<4.3使用@Roman Minenok ValueAnimator方法上面提到。

你可以使用新的属性动画Api来制作彩色动画:

int colorFrom = getResources().getColor(R.color.red);
int colorTo = getResources().getColor(R.color.blue);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(250); // milliseconds
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(ValueAnimator animator) {
        textView.setBackgroundColor((int) animator.getAnimatedValue());
    }

});
colorAnimation.start();

向后兼容Android 2。x使用Jake Wharton的九个旧android库。

getColor方法在Android M中已弃用,所以你有两个选择:

如果你使用支持库,你需要用以下语句替换getColor调用: ContextCompat。色鬼(这个,R.color.red); 如果你不使用支持库,你需要将getColor调用替换为: 色鬼(R.color.red);

罗曼米诺克回答在kotlin和作为扩展函数

fun View.colorTransition(@ColorRes startColor: Int, @ColorRes endColor: Int, duration: Long = 250L){
    val colorFrom = ContextCompat.getColor(context, startColor)
    val colorTo =  ContextCompat.getColor(context, endColor)
    val colorAnimation: ValueAnimator = ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo)
    colorAnimation.duration = duration

    colorAnimation.addUpdateListener {
        if (it.animatedValue is Int) {
            val color=it.animatedValue as Int
            setBackgroundColor(color)
        }
    }
    colorAnimation.start()
}

如果你想改变当前的背景色到新的颜色,那么你可以使用这个

fun View.colorTransition(@ColorRes endColor: Int, duration: Long = 250L){
    var colorFrom = Color.TRANSPARENT
    if (background is ColorDrawable)
        colorFrom = (background as ColorDrawable).color

    val colorTo =  ContextCompat.getcolor(context, endColor)
    val colorAnimation: ValueAnimator = ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo)
    colorAnimation.duration = duration

    colorAnimation.addUpdateListener {
        if (it.animatedValue is Int) {
            val color=it.animatedValue as Int
            setBackgroundColor(color)
        }
    }
    colorAnimation.start()
}

使用

myView.colorTransition(R.color.bg_color)

如果你想要这样的彩色动画,

这段代码将帮助你:

ValueAnimator anim = ValueAnimator.ofFloat(0, 1);   
anim.setDuration(2000);

float[] hsv;
int runColor;
int hue = 0;
hsv = new float[3]; // Transition color
hsv[1] = 1;
hsv[2] = 1;
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {

        hsv[0] = 360 * animation.getAnimatedFraction();

        runColor = Color.HSVToColor(hsv);
        yourView.setBackgroundColor(runColor);
    }
});

anim.setRepeatCount(Animation.INFINITE);

anim.start();

关于XML驱动动画的文档非常糟糕。我已经搜索了大约几个小时,只是为了在按下按钮时使背景颜色动画化…遗憾的是动画只有一个属性:你可以在选择器中使用exitFadeDuration:

<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:exitFadeDuration="200">

    <item android:state_pressed="true">
        <shape android:tint="#3F51B5" />
    </item>

    <item>
        <shape android:tint="#F44336" />
    </item>

</selector>

然后将它用作视图的背景。不需要Java/Kotlin代码。