Animate change of view background color on Android

前端 未结 16 695
孤街浪徒
孤街浪徒 2020-11-22 13:23

How do you animate the change of background color of a view on Android?

For example:

I have a view with a red background color. The background color of the

相关标签:
16条回答
  • 2020-11-22 14:02

    I ended up figuring out a (pretty good) solution for this problem!

    You can use a TransitionDrawable to accomplish this. For example, in an XML file in the drawable folder you could write something like:

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

    Then, in your XML for the actual View you would reference this TransitionDrawable in the android:background attribute.

    At this point you can initiate the transition in your code on-command by doing:

    TransitionDrawable transition = (TransitionDrawable) viewObj.getBackground();
    transition.startTransition(transitionTime);
    

    Or run the transition in reverse by calling:

    transition.reverseTransition(transitionTime);
    

    See Roman's answer for another solution using the Property Animation API, which wasn't available at the time this answer was originally posted.

    0 讨论(0)
  • 2020-11-22 14:03

    add a folder animator into res folder. (the name must be animator). Add an animator resource file. For example res/animator/fade.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <objectAnimator
            android:propertyName="backgroundColor"
            android:duration="1000"
            android:valueFrom="#000000"
            android:valueTo="#FFFFFF"
            android:startOffset="0"
            android:repeatCount="-1"
            android:repeatMode="reverse" />
    </set>
    

    Inside Activity java file, call this

    View v = getWindow().getDecorView().findViewById(android.R.id.content);
    AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.fade);
    set.setTarget(v);
    set.start();
    
    0 讨论(0)
  • 2020-11-22 14:05

    best way is to use ValueAnimator and ColorUtils.blendARGB

     ValueAnimator valueAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
     valueAnimator.setDuration(325);
     valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
    
                  float fractionAnim = (float) valueAnimator.getAnimatedValue();
    
                  view.setBackgroundColor(ColorUtils.blendARGB(Color.parseColor("#FFFFFF")
                                        , Color.parseColor("#000000")
                                        , fractionAnim));
            }
    });
    valueAnimator.start();
    
    0 讨论(0)
  • 2020-11-22 14:06

    Based on ademar111190's answer, I have created this method the will pulse the background color of a view between any two colors:

    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();
    }
    
    0 讨论(0)
  • 2020-11-22 14:07

    Here's a nice function that allows this:

    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();
        }
    }
    

    And in Kotlin:

    @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()
        }
    }
    
    0 讨论(0)
  • 2020-11-22 14:09

    The documentation on XML powered animations is horrible. I've searched around hours just to animate the background color of a button when pressing... The sad thing is that the animation is only one attribute away: You can use exitFadeDuration in the selector:

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

    Then just use it as background for your view. No Java/Kotlin code needed.

    0 讨论(0)
提交回复
热议问题