Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CircularReveal animation doesn't work on first attempt

In android 5.0 i am trying to work with circular reveal animation

Problem

When i click on button to start reveal animation, on first click animation doesn't start

Second Click onwards it works normally

My Code

public class MainActivity extends ActionBarActivity {

Animator a;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final View cardType = findViewById(R.id.cardtype);
    cardType.setVisibility(View.GONE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        a = ViewAnimationUtils.createCircularReveal(cardType,
                cardType.getWidth(),
                cardType.getHeight(),
                0,
                cardType.getHeight() * 2)
                .setDuration(2500);
        a.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                cardType.setVisibility(View.VISIBLE);
            }
        });
        a.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                cardType.setVisibility(View.GONE);
            }
        });
        findViewById(R.id.icon_first_activity).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                a.start();
            }
        });
    }
}}
like image 759
architjn Avatar asked Jan 11 '15 15:01

architjn


2 Answers

I haven't tried your code, but I think you have a small ordering problem. I think you just need to set the cardType visible before you start the animation.

Edited to add:

... and you should be setting your button View.INVISIBLE, not View.GONE.

Here: This code works.

Edited once more to add:

Yes. Your problem is that you set the view GONE initially. That means it has 0 size. Then you use cardType.getHeight and cardType.getWidth as reveal coordinates. They are 0. You are going to want to set the view INVISIBLE, initially, and then use width/2 and height/2 as the center of the reveal.

like image 109
G. Blake Meike Avatar answered Nov 11 '22 21:11

G. Blake Meike


Basically what others answers say, it's correct, but the problem is if you want visibility GONE (because your layout requires it GONE!) you have to set visibility INVISIBLE in the xml with height 0dp (and/or width 0dp as well) and programmatically set the correct LayoutParams even inside the click event it will work. For example my code:

    ...
    expandButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //To not have empty scroll, the container is INVISIBLE with 0dp height.
            //Otherwise the Reveal effect will not work at the first click.
            //Here I set the parameters programmatically.
            viewContainer.setLayoutParams(new LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));

            if (viewContainer.getVisibility() == View.VISIBLE) {
                expandButton.animate().rotation(0f).setDuration(duration).start();
                Utils.unReveal(viewContainer, 0, 0);
            } else {
                expandButton.animate().rotation(180f).setDuration(duration).start();
                Utils.reveal(viewContainer, viewContainer.getWidth(), 0);
            }
        }
    });
    ...

@TargetApi(VERSION_CODES.LOLLIPOP)
public static void reveal(final View view, int cx, int cy) {
    if (!hasLollipop()) {
        view.setVisibility(View.VISIBLE);
        return;
    }

    //Get the final radius for the clipping circle
    int finalRadius = Math.max(view.getWidth(), view.getHeight());

    //Create the animator for this view (the start radius is zero)
    Animator animator =
            ViewAnimationUtils.createCircularReveal(view, cx, cy, 0, finalRadius);

    //Make the view VISIBLE and start the animation
    view.setVisibility(View.VISIBLE);
    animator.start();
}

@TargetApi(VERSION_CODES.LOLLIPOP)
public static void unReveal(final View view, int cx, int cy) {
    if (!hasLollipop()) {
        view.setVisibility(View.GONE);
        return;
    }

    //Get the initial radius for the clipping circle
    int initialRadius = view.getWidth();

    //Create the animation (the final radius is zero)
    Animator animator =
        ViewAnimationUtils.createCircularReveal(view, cx, cy, initialRadius, 0);

    //Make the view GONE when the animation is done
    animator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            view.setVisibility(View.GONE);
        }
    });

    //Start the animation
    animator.start();
}

If you set only GONE in the xml, the first time will never work because height/width/x/y/etc.. are 0. Also, if you just set INVISIBLE before the call to the animation it will not work as well, but if you start with visibility INVISIBLE it will initialize the layout params.

like image 35
Davideas Avatar answered Nov 11 '22 22:11

Davideas