【发布时间】:2017-02-09 11:04:45
【问题描述】:
为长标题道歉。我的问题如下:我使用 DialogFragment 来防止 AlertDialogs 在旋转时被解除(类似于这里的答案:Prevent dialog dismissal on screen rotation in Android)。
现在,我在后台运行一些可能需要几秒钟的任务。我想显示一个进度对话框来告诉用户发生了什么。任务完成后,ProgressDialog 应该从 AsyncTask 中的完成方法中关闭。
与上面的链接一样,我使用 DialogFragment 创建一个 Dialog。对话框在旋转时保留(这很好)。然而,一旦我的任务完成并且屏幕被旋转,我就无法关闭对话框。
以下是我尝试过的策略(如果不旋转屏幕,这两种方法都有效):
- 调用 DialogFragment 的“dismiss()”。屏幕旋转后,这会导致崩溃 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“android.app.FragmentTransaction android.app.FragmentManager.beginTransaction()” android.app.DialogFragment.dismissInternal(DialogFragment.java:296) android.app.DialogFragment.dismiss(DialogFragment.java:267)
- 调用一些调用“getDialog().dismiss()”的内部方法:getDialog() 始终返回 null(旋转后),尽管显示了对话框。
有人能引导我走向正确的方向吗?
编辑:这是一些代码
在 Activity 内部,我只是创建了一个 TaskFragment 来做一些后台工作:
public class MainActivity extends AppCompatActivity {
private TaskFragment ft;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ft = (TaskFragment) getFragmentManager().findFragmentByTag("task");
if(ft == null) {
// create new
ft = TaskFragment.newInstance();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(ft, "task");
transaction.commit();
}
}
}
在 TaskFragment 中,我运行了一个 AsyncTask。在 onPreExecute 我显示一个 ProgressDialog,在 onPostExecute 我关闭它:
public class TaskFragment extends Fragment {
public static TaskFragment newInstance() {
return new TaskFragment();
}
public TaskFragment() {}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRetainInstance(true);
// Run a background task and show a dialog
new AsyncTask<Void, Void, Void>() {
MyDialogFragment ft;
@Override
protected void onPreExecute() {
// show progress dialog
ft = MyDialogFragment.newInstance();
ft.show(getActivity().getFragmentManager(), "dialog");
}
@Override
protected Void doInBackground(Void...params) {
try {
// Do some work...
Thread.sleep(5000);
} catch (InterruptedException ignored) {}
return null;
}
@Override
protected void onPostExecute(Void p) {
// remove progress dialog
ft.dismiss();
}
}.execute();
}
}
DialogFragment 如下:
public class MyDialogFragment extends DialogFragment {
public static MyDialogFragment newInstance() {
MyDialogFragment fragment = new MyDialogFragment();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setCancelable(false);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
ProgressDialog dialog = new ProgressDialog(getActivity());
dialog.setIndeterminate(true);
dialog.setTitle("Hello World");
return dialog;
}
}
感谢和最好的问候, 卡尔
【问题讨论】:
-
最小代码在哪里? ...
-
刚刚添加了最少的代码。感谢您的代码,我认为它为我指明了正确的方向(我认为 DialogFragments 被保留并且在旋转后不会重新创建)。会检查。谢谢(很抱歉没有首先添加最小的代码示例。
-
正如您在我的链接中看到的那样,DialogFragment 应该包含“工作”片段
-
我的 JobFragment 要大得多,我只需要进度对话框来提供一些初始化代码比预期花费的时间更长的反馈。事实上,我会在 1 秒后检查初始化是否完成,然后才显示对话框。
标签: android dialog progressdialog android-dialogfragment dialogfragment