Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FloatingActionButton icon animation (Android FAB src drawable animation)

I was trying to find documentation about how to create icon animation of FAB's (of the Design support library), after searching a while i couldn't find any information about it and the AnimationDrawable reference in android developers doesn't work for FAB's even if the class is a child of ImageView.

but manage to get a workaround that works just fine.

like image 445
Danfoa Avatar asked Jul 18 '15 03:07

Danfoa


2 Answers

You can achieve FAB's src drawable animation quite similarly to other views that use background for AnimationDrawable.

For general views' background drawable animation, see Use AnimationDrawable.

However, you cannot call getBackground() to get FAB's src.

Instead, use getDrawable().

Example:

        FloatingActionButton loginButton = findViewById(R.id.loginButton);
        loginAnimation = (AnimationDrawable) loginButton.getDrawable();

        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loginAnimation.start();
            }
        });
like image 96
Rui Ying Avatar answered Nov 04 '22 14:11

Rui Ying


The technic I used is similar to the one exposed on the DrawableAnimation documentation, and using the Property Animation API doc.

First I use the ValueAnimator class, and an int array containing the ids of the drawables that you're going to use in your animation.

    final int[] ids = {R.drawable.main_button_1,R.drawable.main_button_2,R.drawable.main_button_3,R.drawable.main_button_4,R.drawable.main_button_5,R.drawable.main_button_6, R.drawable.main_button_7};
    fab = (FloatingActionButton) findViewById(R.id.yourFabID);
    valueAnimator = ValueAnimator.ofInt(0, ids.length - 1).setDuration(yourAnimationTime);
    valueAnimator.setInterpolator( new LinearInterpolator() /*your TimeInterpolator*/ );

Then set up an AnimationUpdateListener, and define the change in icon behavior with the method FloatinActionButton.setImageDrawable(Drawable yourDrawable).

But the ValueAnimator updates by default every available frame (depending on the load in hardware), but we don't need to redraw the icon if it has already been drawn, so that is why I use the variable "i"; so each icon is drawn only once. (the timing depends on the interpolator you define)

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        int i = -1;
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            int animatedValue = (int) animation.getAnimatedValue();
            if(i!=animatedValue) {
                fab.setImageDrawable(getResources().getDrawable(ids[animatedValue]));
                i = animatedValue;
            }
        }
    });

This implementation allows you to play the animation backward with the method ValueAnimator.reverse();

I know is not a pro solution but it's the only one I've figured out to work on all API's supporting the PropertyAnimation. Please, if you know a better solution post it here, if not I hope this post is helpful

like image 35
Danfoa Avatar answered Nov 04 '22 13:11

Danfoa