DialogFragment animation of layout and "Attempting to destroy the window while drawing!" error
Asked Answered
F

5

6

I have a DialogFragment which has some animations of some of the layouts inside its view. When I dismiss the dialog, I want to perform an animation and when the animation has ended, perform the dismiss operation.

Step1: Call the fragment from my activity:

myDialog.show(getSupportFragmentManager(), "");

Step 2: After the user had completed the job with the dialog, he presses a button. That button calls an animation and after that I want the dialog to disappear:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View layout = inflater.inflate(R.layout.my_layout, null);

        layMain = (LinearLayout) layout.findViewById(R.id.layMain);

        TextView btnCancel = (TextView) layout.findViewById(R.id.btnCancel);
            btnCancel.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    final Animation anim = AnimationUtils.loadAnimation(getActivity(), R.anim.translate_to_bottom);
                    anim.setAnimationListener(new AnimationListener() {

                        @Override
                        public void onAnimationStart(Animation animation) {

                        }

                        @Override
                        public void onAnimationRepeat(Animation animation) {

                        }

                        @Override
                        public void onAnimationEnd(Animation animation) {
                            dismiss();
                        }
                    });
                    layMain.startAnimation(anim);
                }
            });
.....

When the animations ends, the dialog gets dismissed but I get this error on logcat

E/ViewRootImpl(25507): Attempting to destroy the window while drawing! E/ViewRootImpl(25507): window=android.view.ViewRootImpl@427348e0, title=com.mypackage/com.mypackage.MyActivity

How can I prevent this ?

Later edit: if I am using it without any animation, everything works fine and no error is shown on logcat. So I suppose it has to do something with the animation.

The animation I am using:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false" >

  <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromYDelta="0%p"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toYDelta="80%p" />

</set>
Fifine answered 29/7, 2013 at 12:6 Comment(10)
that means that your dialog has been not disappeared??Brushwood
The dialog disappears as the normal expectation. So everything behaves normal, except that error message which.. can't mean something good.Fifine
This is because you have pass the getSupportFragmentManager() as a context object...so instead of it you have pass getActivity()....Brushwood
I don't understand your answer, could you please elaborate a bit ? The thing is, if I am using it without an animation, dismiss does not generate the error. So it has to be something with the animation.Fifine
What do you do in that animation(maybe stepping outside of the dialog)? You can always use one of the dialog views to post() a Runnable on it with the dismiss() call.Cordilleras
In the animation I am taking the root layout of the dialog view and slide it to the bottom.Fifine
Did you tried, like I said in the above comment, to post() a Runnable with the dismiss() call on one of the dialog views(like btnCancel)?Cordilleras
You mean something like handler.postDelayed() ?Fifine
No, I was referring more to btnCancel.post(new Runnable() { @Override public void run() {dismiss();}}); in the animationEnd callback.Cordilleras
Can you post your animation file and your layout file. I am trying to recreate this but I am not getting the exception.Promptbook
F
8

The only solution that works so far, without throwing an error is this:

@Override
public void onAnimationEnd(Animation animation) {
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            dismiss();
        }
    }, 10);

}

I am open to any other sugestions

Fifine answered 8/8, 2013 at 6:51 Comment(2)
You don't need the 10 ms delay. You can simply use the post() method.Abscess
This is very late. But today in 2020, using @ItaiHanski solution works. In my case, I am closing the dialog with animation. Overriding the dismiss() method, I put my super.dismiss() method in the OnAnimationEnd(), wrapped by Handler().post { }, as suggested above. Thanks!Macon
B
2

You have pass fragment context as a getSupportFragmentManager(). So you have to change it:

myDialog.show(getFragmentManager(), "");
Brushwood answered 29/7, 2013 at 12:37 Comment(2)
void android.support.v4.app.DialogFragment.show(FragmentManager manager, String tag) requires fragment manager not activity.Fifine
I need to use Support fragment manager as my apps needs to be compatible starting from android 2.2Fifine
A
2

I do not see any such issues:

public class MyDIalog extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final Button b = new Button(getActivity());
        final Dialog d = super.onCreateDialog(savedInstanceState);
        d.setContentView(b);

        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                b.animate().rotationYBy(180).setDuration(500).setListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animator) {
                    }

                    @Override
                    public void onAnimationEnd(Animator animator) {
                        dismiss();
                    }

                    @Override
                    public void onAnimationCancel(Animator animator) {
                    }

                    @Override
                    public void onAnimationRepeat(Animator animator) {
                    }
                });
            }
        });

        return d;
    }

}

works fine with:

new MyDIalog().show(getFragmentManager(),"dialog");

Any ways, you can schedule the dismiss() call a bit later by using:

 @Override
 public void onAnimationEnd(Animator animator) {
   getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
      dismiss();
    }
   });
 }
Adulthood answered 1/8, 2013 at 8:8 Comment(2)
Thanks for your answer. Unfortunately is not working. As I said, if I don't use animations, the error does not occur. The difference from your code is that I am using onCreateView and getSupportFragmentManger. Maybe there is a bug in support library?Fifine
@Fifine Maybe, I tested on emulator with ICS platform, it worked OK.Adulthood
M
0

You can use like this.

@Override 
public void onAnimationEnd(Animation animation) {
    Handler handler = new Handler(); 
    handler.post(new Runnable() {
        @Override 
        public void run() { 
            dismiss(); 
        } 
    }); 
}

here, the advantage is, you don't define your own time, this way it may help to keep everything else simple, as a user can surprise you even within a short duration if dialog kept without dismissing after the animation ends.

Milly answered 26/8, 2015 at 14:6 Comment(0)
H
0

I am not sure if it's too late to answer your question but the only way to get rid of this error is to post the dialogue removal code in a view's post method in your onAnimationEnd().
for example:

view.post(new Runnable() {  
    @Override  
    public void run() {  
        windowManager.removeView(layout);
    } 
});
Hemispheroid answered 26/2, 2019 at 7:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.