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

例如:

我的背景色为红色。 视图的背景颜色变为蓝色。 如何在颜色之间进行平滑过渡?

如果无法通过视图完成此操作,将欢迎使用其他方法。

#1楼

实现此目的的另一种简便方法是使用AlphaAnimation执行淡入。

使您的视图成为ViewGroup

将子视图添加到索引0,具有match_parent布局尺寸

给孩子提供与容器相同的背景

将容器的背景更改为目标颜色

使用AlphaAnimation淡出孩子。

动画完成后删除子级(使用AnimationListener)

#2楼

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的Nine Old Androids库 。

在Android M中不赞成使用getColor方法,因此您有两种选择:

如果使用支持库,则需要将getColor调用替换为:ContextCompat.getColor(this, R.color.red);

如果不使用支持库,则需要将getColor调用替换为:getColor(R.color.red);

#3楼

根据视图获取背景颜色的方式以及目标颜色的方式,有几种不同的方法可以执行此操作。

在以下情况下使用对象动画制作器 :

您的视图的背景色定义为xml文件中的argb值。

您的视图先前已通过view.setBackgroundColor()设置了颜色。

视图的背景色在可绘制对象中定义,该对象不定义任何额外的属性,例如笔触或拐角半径。

视图的背景色在可绘制对象中定义,并且要删除任何额外的属性,例如笔触或拐角半径,请记住,删除这些额外的属性不会产生动画效果。

对象动画师通过调用view.setBackgroundColor来工作,该对象将替换已定义的drawable,除非它是ColorDrawable的实例,但很少出现。 这意味着将删除可绘制对象中任何多余的背景属性(例如笔触或拐角)。

在以下情况下使用值动画器 :

视图的背景颜色在可绘制对象中定义,该对象还设置了诸如笔触或拐角半径的属性,并且您想将其更改为在运行时确定的新颜色。

如果满足以下条件,则使用Transition绘制 :

您的视图应在部署之前已定义的两个可绘制对象之间切换。

我在打开无法解决的DrawerLayout时运行的Transition可绘制对象遇到一些性能问题,因此,如果遇到任何意外的卡顿,您可能会遇到与我相同的错误。

如果要使用StateLists可绘制对象或LayerLists可绘制对象 ,则必须修改Value Animator示例,否则它将在final GradientDrawable background = (GradientDrawable) view.getBackground(); 线。

查看定义:

android:background="#FFFF0000"

android:layout_width="50dp"

android:layout_height="50dp"/>

像这样创建并使用一个ObjectAnimator 。

final ObjectAnimator backgroundColorAnimator = ObjectAnimator.ofObject(view,

"backgroundColor",

new ArgbEvaluator(),

0xFFFFFFFF,

0xff78c5f9);

backgroundColorAnimator.setDuration(300);

backgroundColorAnimator.start();

您还可以像XMight在Android object中那样使用AnimatorInflater从xml中加载动画定义。

查看定义:

android:background="@drawable/example"

android:layout_width="50dp"

android:layout_height="50dp"/>

可绘制的定义:

android:color="#edf0f6"

android:width="1dp"/>

创建和使用ValueAnimator像这样:

final ValueAnimator valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(),

0xFFFFFFFF,

0xff78c5f9);

final GradientDrawable background = (GradientDrawable) view.getBackground();

currentAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(final ValueAnimator animator) {

background.setColor((Integer) animator.getAnimatedValue());

}

});

currentAnimation.setDuration(300);

currentAnimation.start();

查看定义:

android:background="@drawable/example"

android:layout_width="50dp"

android:layout_height="50dp"/>

可绘制的定义:

android:color="#edf0f6"

android:width="1dp"/>

android:color="#68aff4"

android:width="1dp"/>

像这样使用TransitionDrawable:

final TransitionDrawable background = (TransitionDrawable) view.getBackground();

background.startTransition(300);

您可以通过在动画实例上调用.reverse()来反转动画。

还有其他制作动画的方法,但是这三种可能是最常见的。 我通常使用ValueAnimator。

#4楼

这是一个不错的功能,它可以实现以下目的:

public static void animateBetweenColors(final @NonNull View viewToAnimateItsBackground, final int colorFrom,

final int colorTo, final int durationInMs) {

final ColorDrawable colorDrawable = new ColorDrawable(durationInMs > 0 ? colorFrom : colorTo);

ViewCompat.setBackground(viewToAnimateItsBackground, colorDrawable);

if (durationInMs > 0) {

final ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);

colorAnimation.addUpdateListener(animator -> {

colorDrawable.setColor((Integer) animator.getAnimatedValue());

ViewCompat.setBackground(viewToAnimateItsBackground, colorDrawable);

});

colorAnimation.setDuration(durationInMs);

colorAnimation.start();

}

}

在科特林:

@JvmStatic

fun animateBetweenColors(viewToAnimateItsBackground: View, colorFrom: Int, colorTo: Int, durationInMs: Int) {

val colorDrawable = ColorDrawable(if (durationInMs > 0) colorFrom else colorTo)

ViewCompat.setBackground(viewToAnimateItsBackground, colorDrawable)

if (durationInMs > 0) {

val colorAnimation = ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo)

colorAnimation.addUpdateListener { animator: ValueAnimator ->

colorDrawable.color = (animator.animatedValue as Int)

ViewCompat.setBackground(viewToAnimateItsBackground, colorDrawable)

}

colorAnimation.duration = durationInMs.toLong()

colorAnimation.start()

}

}

#5楼

这是我在基本活动中用于更改背景的方法。 我正在使用在代码中生成的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

root.setBackgroundDrawable(newBG);

}else{

root.setBackground(newBG);

}

}else{

TransitionDrawable transitionDrawable = new TransitionDrawable(new Drawable[]{currentBG, newBG});

transitionDrawable.setCrossFadeEnabled(true);

if(Build.VERSION.SDK_INT

root.setBackgroundDrawable(transitionDrawable);

}else{

root.setBackground(transitionDrawable);

}

transitionDrawable.startTransition(400);

}

}

}

更新:万一有人遇到我发现的相同问题,出于某种原因,在Android <4.3上使用setCrossFadeEnabled(true)会导致不良的白化效果,因此我不得不使用@Roman Minenok ValueAnimator方法将<4.3切换为纯色以上。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐