如何在Android上动画化视图的背景颜色变化?
例如:
我有一个红色背景色的视图。视图的背景颜色变为蓝色。我怎样才能在颜色之间平滑过渡呢?
如果视图不能做到这一点,那么另一种选择是受欢迎的。
如何在Android上动画化视图的背景颜色变化?
例如:
我有一个红色背景色的视图。视图的背景颜色变为蓝色。我怎样才能在颜色之间平滑过渡呢?
如果视图不能做到这一点,那么另一种选择是受欢迎的。
当前回答
这是我在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 11上面的ArgbEvaluatorCompat类。
implementation 'com.google.android.material:material:1.0.0'
ValueAnimator colorAnim = ValueAnimator.ofObject(new ArgbEvaluatorCompat(), startColor, endColor);
colorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mTargetColor = (int) animation.getAnimatedValue();
}
});
colorAnim.start();
你可以创建一个对象动画器。例如,我有一个targetView,我想改变你的背景颜色:
int colorFrom = Color.RED;
int colorTo = Color.GREEN;
int duration = 1000;
ObjectAnimator.ofObject(targetView, "backgroundColor", new ArgbEvaluator(), colorFrom, colorTo)
.setDuration(duration)
.start();
在Kotlin中使用以下函数:
private fun animateColorValue(view: View) {
val colorAnimation =
ValueAnimator.ofObject(ArgbEvaluator(), Color.GRAY, Color.CYAN)
colorAnimation.duration = 500L
colorAnimation.addUpdateListener { animator -> view.setBackgroundColor(animator.animatedValue as Int) }
colorAnimation.start()
}
传递任何你想改变颜色的视图。
罗曼米诺克回答在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)
我最终想出了一个(非常好的)解决这个问题的方法!
你可以使用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的另一个解决方案的答案,在这个答案最初发布时还不可用。