简体   繁体   English

屏幕方向更改后关闭对话框

[英]Dismiss dialog after screen orientation change

1) I launch a background task (via AsyncTask) 1)我启动后台任务(通过 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) 2)仍在主线程中(就在新线程启动之前)我用 showDialog(dialogId) 创建了一个对话框

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

3) Screen orientation changes and the Activity is recreated 3)屏幕方向改变,重新创建Activity

4) How can I now dismiss the dialog from the FindJourneyTask? 4) 我现在如何关闭 FindJourneyTask 中的对话框? Calling dismissDialog(dialogId) does nothing.调用 dismissDialog(dialogId) 什么都不做。

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

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. 同时,您在之前使用的Dialog在新的Activity中重新创建,但旧的后台任务在尝试关闭对话框时仍然引用旧的Activity。 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() . 创建一个引用Activity本身的Activity的静态成员变量,这样就可以调用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/ 这三个解决方案在这里详细讨论: http//groups.google.com/group/android-developers/browse_thread/thread/bf046b95cf38832d/

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. 如果使用DialogFragment创建对话框,则此片段将负责维护对话框的生命周期。 When you show a dialog, you supply a tag for your fragment ( DialogFragment.show() ). 显示对话框时,为片段提供标记( 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. 当您需要访问对话框时,只需使用FragmentManager.findFragmentByTag查找必要的DialogFragment,而不是引用对话框本身。

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: 这里有一些基于@peresisUser答案的代码:

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

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. 我检查onSavedInstance(),它运行方向更改,对话框是否显示dialog.isShowing(),并将其传递给outState变量。 Then in your onCreate(), you check this var if it's true. 然后在你的onCreate()中,检查这个var是否为真。 If it is, you simply dismiss your dialog with dialog.dismiss() 如果是,你只需用dialog.dismiss()忽略你的对话框

Hope this helps others :() 希望这有助于其他人:()

I tried adding setRetainInstance(true); 我尝试添加setRetainInstance(true); on OnCreate function of DialogFragment . 关于DialogFragment OnCreate函数。 This will cause dialog to dismiss on rotation. 这将导致对话框在旋转时消失。

Just add this line to specific activity in your Manifest to solve this problem android:configChanges="orientation|screenSize|smallestScreenSize"只需将此行添加到清单中的特定活动即可解决此问题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" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM