在Android上对视图背景颜色进行动画处理

大兔子大兔子 提交于 2020-03-19 21:26:40

3 月,跳不动了?>>>

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

例如:

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

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


#1楼

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

  1. 使您的视图成为ViewGroup
  2. 将子视图添加到索引0,具有match_parent布局尺寸
  3. 给孩子提供与容器相同的背景
  4. 将容器的背景更改为目标颜色
  5. 使用AlphaAnimation淡出孩子。
  6. 动画完成后删除子级(使用AnimationListener)

#2楼

您可以将新的Property Animation 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的Nine Old Androids库

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

  • 如果使用支持库,则需要将getColor调用替换为:

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

    getColor(R.color.red);

#3楼

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

前两个使用Android Property Animation框架。

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

  • 您的视图的背景色定义为xml文件中的argb值。
  • 您的视图先前已通过view.setBackgroundColor()设置了颜色。
  • 视图的背景色在可绘制对象中定义,该对象定义任何额外的属性,例如笔触或拐角半径。
  • 视图的背景色在可绘制对象中定义,并且要删除任何额外的属性,例如笔触或拐角半径,请记住,删除这些额外的属性不会产生动画效果。

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

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

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

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

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

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

如果要使用StateLists可绘制对象LayerLists可绘制对象 ,则必须修改Value Animator示例,否则它将在final 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();

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

价值动画师

查看定义:

<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。


#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<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)会导致不良的白化效果,因此我不得不使用@Roman Minenok ValueAnimator方法将<4.3切换为纯色以上。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!