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

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.


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.


what i did is, Like i have two view with same height,As we now visibility gone returns 0 {height and width} than i am giving visible view height every time and its work for me.


The solution is don't get values directly into code Either put the animation code on click and the values outside onclick or get the values from other activity By values i mean cardType.getWidth() and cardType.getHeight()


Need Your Help

Append date to filename in linux

linux ubuntu append rename filenames

I want add the date next to a filename ("somefile.txt"). For example: somefile_25-11-2009.txt or somefile_25Nov2009.txt or anything to that effect

Cast to generic type in C#

c# generics casting

I have a Dictionary to map a certain type to a certain generic object for that type. For example: