fhucho
fhucho

Reputation: 34530

Dismiss dialog after screen orientation change

1) I launch a background task (via AsyncTask)

new FindJourneyTask().execute(); // FindJourneyTask extends AsyncTask

2) Still in the main thread (just before new thread is launched) I create a dialog with showDialog(dialogId)

// this method is in FindJourneyTask
protected void onPreExecute() {
    showDialog(DIALOG_FINDING_JOURNEY);
}

3) Screen orientation changes and the Activity is recreated

4) How can I now dismiss the dialog from the FindJourneyTask? Calling dismissDialog(dialogId) does nothing.

// this method is in FindJourneyTask
protected void onPostExecute(FindJourneyResult result) {
    dismissDialog(DIALOG_FINDING_JOURNEY); // does nothing
}

Upvotes: 15

Views: 13186

Answers (6)

Gregorian
Gregorian

Reputation: 11

A very simplified workaround:

public class RenameDeckDialog extends DialogFragment{
      
  private final boolean isRotated;
  
  // This constructor is used to recreation after screen rotation
  public RenameDeckDialog() {
    // Dimiss on screen rotation
    isRotated = true;
  }
  
  // This constructor is used for initialization for the first time
  public RenameDeckDialog(your params) {
    this.deckDbPath = deckDbPath;
    isRotated = false;
  }

  @Override
  public void onResume() {
    super.onResume();
    if (isRotated) dismiss();
  }
}

Upvotes: 0

EAS
EAS

Reputation: 477

Just add this line to specific activity in your Manifest to solve this problem android:configChanges="orientation|screenSize|smallestScreenSize"

like this,

        <activity
            android:name=".PDFTools"
            android:exported="false"
            android:configChanges="orientation|screenSize|smallestScreenSize"
            android:theme="@style/Theme.DocScanner.NoActionBar" />

Upvotes: 0

Stakshi
Stakshi

Reputation: 389

I tried adding setRetainInstance(true); on OnCreate function of DialogFragment. This will cause dialog to dismiss on rotation.

Upvotes: 2

Malcolm
Malcolm

Reputation: 41510

There is a better solution to this problem now which involves using fragments.

If you create a dialog using DialogFragment, then this fragment will be responsible for maintaining your dialog's lifecycle. When you show a dialog, you supply a tag for your fragment (DialogFragment.show()). When you need to access your dialog, you just look for the necessary DialogFragment using FragmentManager.findFragmentByTag instead of having a reference to the dialog itself.

This way if device changes orientation, you will get a new fragment instead of the old one, and everything will work.

Here's some code based also in @peresisUser answer:

public void onSaveInstanceState(Bundle outState) {
   AppCompatActivity activity = (AppCompatActivity) context;
   FragmentManager fragmentManager = activity.getSupportFragmentManager();
   DialogFragment dialogFragment = (DialogFragment) fragmentManager.findFragmentByTag("your_dialog_tag");
   if(dialogFragment!=null) {
      Dialog dialog = dialogFragment.getDialog();
      if(dialog!=null && dialog.isShowing()) {
         dialogFragment.dismiss();
      }
   }
}

Upvotes: 12

peresisUser
peresisUser

Reputation: 1686

This is long after the question was asked and answered, but i stumbled upon this problem also and wanted to share my solution...

I check in onSavedInstance() which runs on orientation change, whether the dialog is showing or not with dialog.isShowing(), and pass it into outState variable. Then in your onCreate(), you check this var if it's true. If it is, you simply dismiss your dialog with dialog.dismiss()

Hope this helps others :()

Upvotes: 4

Dan Lew
Dan Lew

Reputation: 87430

This is a common problem, and there are no real good solutions. The issue is that on screen orientation change, the entire Activity is destroyed and recreated. At the same time, the Dialog you previously had is re-created in the new Activity, but the old background task still refers to the old Activity when it tries to dismiss the dialog. The result is that it dismisses a dialog which was long ago destroyed, rather than dismissing the dialog the new orientation created.

There are three basic solutions:

  1. Override the default orientation-handling code so that your Activity is not destroyed upon rotation. This is probably the least satisfactory answer, as it blocks a lot of code that is automatically run upon orientation changes.

  2. Create a static member variable of your Activity that references the Activity itself, so you can call STATIC_ACTIVITY_VARIABLE.dismissDialog().

  3. Code a solution in which the background task keeps track of the current Activity and updates itself as necessary.

These three solutions are discussed at length here: http://groups.google.com/group/android-developers/browse_thread/thread/bf046b95cf38832d/

Upvotes: 22

Related Questions