如何在Android上动画化视图的背景颜色变化?
例如:
我有一个红色背景色的视图。视图的背景颜色变为蓝色。我怎样才能在颜色之间平滑过渡呢?
如果视图不能做到这一点,那么另一种选择是受欢迎的。
如何在Android上动画化视图的背景颜色变化?
例如:
我有一个红色背景色的视图。视图的背景颜色变为蓝色。我怎样才能在颜色之间平滑过渡呢?
如果视图不能做到这一点,那么另一种选择是受欢迎的。
当前回答
你可以使用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();
其他回答
我最终想出了一个(非常好的)解决这个问题的方法!
你可以使用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的另一个解决方案的答案,在这个答案最初发布时还不可用。
你可以使用新的属性动画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);
我发现ArgbEvaluator在Android源代码中使用的实现在转换颜色方面做得最好。当使用HSV时,根据两种颜色,过渡对我来说跳过了太多的色调。但是这个方法没有。
如果你想简单地做动画,使用ArgbEvaluator和ValueAnimator,如下所示:
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
view.setBackgroundColor((int) animator.getAnimatedValue());
}
});
colorAnimation.start();
然而,如果你像我一样,想要将你的转换与一些用户手势或其他输入传递的值绑定在一起,ValueAnimator就没有多大帮助了(除非你的目标是API 22及以上,在这种情况下,你可以使用ValueAnimator. setcurrentfraction()方法)。当目标是API 22以下的代码时,将ArgbEvaluator源代码中找到的代码包装在你自己的方法中,如下所示:
public static int interpolateColor(float fraction, int startValue, int endValue) {
int startA = (startValue >> 24) & 0xff;
int startR = (startValue >> 16) & 0xff;
int startG = (startValue >> 8) & 0xff;
int startB = startValue & 0xff;
int endA = (endValue >> 24) & 0xff;
int endR = (endValue >> 16) & 0xff;
int endG = (endValue >> 8) & 0xff;
int endB = endValue & 0xff;
return ((startA + (int) (fraction * (endA - startA))) << 24) |
((startR + (int) (fraction * (endR - startR))) << 16) |
((startG + (int) (fraction * (endG - startG))) << 8) |
((startB + (int) (fraction * (endB - startB))));
}
你想怎么用就怎么用。
这是我在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方法上面提到。
在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()
}
传递任何你想改变颜色的视图。