Android - 在 DialogFragment 中确定 ProgressDialog

Android - Determinate ProgressDialog inside DialogFragment

我知道 Google 的 Material 设计指南不建议使用 ProgressDialog,而是使用另一种侵入性较小的方式来显示进度,但我需要为特定的情况使用 ProgressDialog Activity 我的应用程序。

所以,问题是我想将 ProgressDialog 包装在 DialogFragment 中,因此我的代码如下:

public class MaterialProgressDialogFragment extends DialogFragment {

private int total;
private MaterialDialog myDialog;

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    return myDialog;
}

public void incrementProgress(int by) {
    myDialog.incrementProgress(by);
}

public void setTotal(int total) {
    this.total = total;
}

public void setUp(Context context) {
    myDialog = new MaterialDialog.Builder(context)
            .title("Progress")
            .content("Processing...")
            .progress(false, total, true)
            .build();
}

}

因为我想要构建的是一个确定的 ProgressDialog,所以我希望能够在我的应用程序的整个生命周期中更新它的进度。为此,我创建了一个名为 setProgress(progress) 的方法,但 myDialog 以及从 getDialog() 返回的值始终为 null。

我做错了什么?

谢谢

编辑:我在片段的 onCreateActivity() 方法中显示对话框,如下所示:

MaterialProgressDialogFragment dialogFragment = new MaterialProgressDialogFragment();
dialogFragment.setTotal(100);
dialogFragment.setUp(getActivity());
dialogFragment.show(getSupportFragmentManager(), "");
dialog.incrementProgress(50);

直到最后一行,一切都按预期工作,这导致应用程序抛出异常。

不完全清楚 setProgress(int progress) 方法中的变量 dialog 是什么。但是如果你的意思是 getDialog() ,那么通过对话框片段创建对话框需要时间,并且在 dialogFragment.show(getSupportFragmentManager(), "")onCreateDialog(Bundle savedInstanceState) 回调之间会有一些时间间隔,在此期间 getDialog() 将 return null.

编辑: 好的,现在更清楚了。但是通过上面的代码,您违反了片段框架规则。您应该在 onCreateDialog(Bundle savedInstanceState) 方法中创建对话框,否则您将遇到生命周期问题(例如,如果您旋转屏幕,应用程序将崩溃)。

我建议你使用类似的东西:

public class MaterialProgressDialogFragment extends DialogFragment {

    public static final String TOTAL_KEY = "total";

    public static ProgressDialogFragment newInstance(int total) {
        Bundle args = new Bundle();
        args.putInt(TOTAL_KEY, total);
        ProgressDialogFragment pdf = new ProgressDialogFragment();
        pdf.setArguments(args);
        return pdf;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        MaterialDialog myDialog = new MaterialDialog.Builder(context)
                .title("Progress")
                .content("Processing...")
                .progress(false, getTotal(), true)
                .build();
        return myDialog;
    }

    public void incrementProgress(int by) {
        if (getDialog()!=null)
            ((MaterialDialog)getDialog()).incrementProgress(by);
    }

    public int getTotal() {
        return getArguments().getInt(TOTAL_KEY);
    }
}

您应该将 total 变量保存到参数中,因为它会在配置更改时被销毁(例如屏幕旋转)。

然后通过以下方式创建并显示它:

MaterialProgressDialogFragment dialogFragment = MaterialProgressDialogFragment.newInstance(100);
dialogFragment.show(getSupportFragmentManager(), "");

如果您想更改进度,请致电:

dialog.incrementProgress(50);

但是请记住,不会立即创建对话框,因此如果您在 show() 之后立即调用它,它不会生效,因为 getDialog() 将 return 为空。如果你只想测试它,请延迟调用它:

new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                dialog.incrementProgress(50);
            }
        }, 200);

但是无论如何在真实的应用程序中你会从一些后台进程改变你的进度。