如何在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方法上面提到。
其他回答
根据视图获取背景颜色的方式以及获取目标颜色的方式,有几种不同的方法可以做到这一点。
前两个使用Android属性动画框架。
在以下情况下使用对象动画器:
视图的背景颜色定义为xml文件中的argb值。 你的视图之前已经由view设置了它的颜色。 视图的背景颜色定义在一个drawable中,它没有定义任何额外的属性,如笔画或角半径。 你的视图有它的背景颜色定义在一个可绘制的,你想要删除任何额外的属性,如笔画或角半径,请记住,删除额外的属性将不会动画。
对象动画器通过调用view来工作。setBackgroundColor替换已定义的drawable,除非它是ColorDrawable的实例,但它很少是。这意味着任何来自可绘制对象的额外背景属性(如描边或角)都将被删除。
在以下情况下使用值动画器:
你的视图有它的背景颜色定义在一个可绘制的,还设置属性,如笔画或角半径和你想改变它为一个新的颜色,这是在运行时决定的。
在以下情况下使用过渡绘制:
视图应该在部署前定义的两个可绘制对象之间切换。
我有一些性能问题与过渡绘图运行,而我正在打开一个抽屉布局,我还没有能够解决,所以如果你遇到任何意外的口吃,你可能会遇到相同的bug,我有。
如果你想使用StateLists可绘制对象或LayerLists可绘制对象,你必须修改Value Animator的例子,否则它会在最终的GradientDrawable background = (GradientDrawable) view.getBackground();线。
对象动画:
视图定义:
<View
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();
你也可以从xml中使用AnimatorInflater加载动画定义,就像XMight在Android中的objectAnimator animate backgroundColor of Layout
动画师的值:
视图定义:
<View
android:background="@drawable/example"
android:layout_width="50dp"
android:layout_height="50dp"/>
可拉的定义:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF"/>
<stroke
android:color="#edf0f6"
android:width="1dp"/>
<corners android:radius="3dp"/>
</shape>
像这样创建并使用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();
可拉的转变:
视图定义:
<View
android:background="@drawable/example"
android:layout_width="50dp"
android:layout_height="50dp"/>
可拉的定义:
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="#FFFFFF"/>
<stroke
android:color="#edf0f6"
android:width="1dp"/>
<corners android:radius="3dp"/>
</shape>
</item>
<item>
<shape>
<solid android:color="#78c5f9"/>
<stroke
android:color="#68aff4"
android:width="1dp"/>
<corners android:radius="3dp"/>
</shape>
</item>
</transition>
像这样使用TransitionDrawable:
final TransitionDrawable background = (TransitionDrawable) view.getBackground();
background.startTransition(300);
你可以通过在动画实例上调用.reverse()来反转动画。
还有其他制作动画的方法,但这三种可能是最常见的。我通常使用ValueAnimator。
关于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代码。
基于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();
答案可以从很多方面给出。你也可以使用ValueAnimator的ofArgb(startColor,endColor)。
火灾> 21:
int cyanColorBg = ContextCompat.getColor(this,R.color.cyan_bg);
int purpleColorBg = ContextCompat.getColor(this,R.color.purple_bg);
ValueAnimator valueAnimator = ValueAnimator.ofArgb(cyanColorBg,purpleColorBg);
valueAnimator.setDuration(500);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
relativeLayout.setBackgroundColor((Integer)valueAnimator.getAnimatedValue());
}
});
valueAnimator.start();