DialogFragment.getDialog 返回 null

Posted

技术标签:

【中文标题】DialogFragment.getDialog 返回 null【英文标题】:DialogFragment.getDialog returns null 【发布时间】:2012-01-17 08:58:57 【问题描述】:

我正在尝试使用DialogFragment.getDialog() 获取使用扩展DialogFragment 创建的Dialog,但它返回null。

基本上,我想从创建并显示DialogFragmentFragmentActivity 更改布局中的文本。

【问题讨论】:

你解决了吗?我遇到了同样的问题 【参考方案1】:

您在DialogFragment 的生命周期中调用getDialog() 太早了。

getDialog() 只是从DialogFragment 返回私有变量mDialog

DialogFragment 被实例化时,mDialog 为空,然后在getLayoutInflater(Bundle savedInstanceState) 内部触发onCreateDialog 时设置它,因此您必须在onCreateDialog 之后调用getDialog

例如,一些常用方法的调用顺序为onCreateonCreateDialogonCreateViewonStart。因此,您可以调用getDialog 并让它在onCreateViewonStart 中返回一些内容,但不能在onCreateonCreateDialog 中返回。

即使onStart 被称为called when the Fragment is visible to the user,在该点调整片段的布局看起来还不错....例如使用getDialog().getWindow().setLayout(..., ...); 设置宽度和高度不会使片段看起来改变大小,但似乎具有新设置的大小。

【讨论】:

即使在 onCreateView、onStart 和 onResume 中,getDialog() 也会为我返回 null ...有什么建议吗? 我似乎仍然无法弄清楚。我来自这个问题:***.com/questions/14907104/…我的对话框扩大了手机的整个宽度,这是不应该的。它没有扩展整个长度的内容。这太烦人了,因为根据那个答案,我必须在显示后调用 setLayoutParams,如果我继承了 DialogFragment 显然我无法做到:/【参考方案2】:

尝试从可用的 FragmentManager 调用 executePendingTransactions()。

    dialogFragment = new DialogFragment();
        ...
    dialogFragment.show(mFragmentActivity.getSupportFragmentManager(), "Dialog");
    mFragmentActivity.getSupportFragmentManager().executePendingTransactions();

    Dialog d = dialogFragment.getDialog()
        ...

【讨论】:

这是由于延迟执行事务更改。我们可以通过调用 FragmentManager 类的 executePendingTransactions() 方法来强制 FragmentTransaction 实例的工作立即执行。当对 executePendingExecutions() 方法的调用返回时,我们知道所有已提交的 FragmentTransaction 工作都已执行。 有效!但这是一个多么晦涩难懂的电话——我原以为 .show 会触发所有待处理的片段【参考方案3】:

DialogFragment 有两种显示方式:

  void showDialog()  
    // Create the fragment and show it as a dialog. 
    DialogFragment newFragment = MyDialogFragment.newInstance(); 
    newFragment.show(getFragmentManager(), "dialog");
 

 FragmentTransaction ft = getFragmentManager().beginTransaction();
DialogFragment newFragment = MyDialogFragment.newInstance(); 
ft.add(R.id.embedded, newFragment);
ft.commit(); 

使用第一种方式只能得到非空对话框。

【讨论】:

有没有办法使用第二种方法设置对话框位置? 使用第一种情况,我在某​​些设备上仍然有getDialog() = null(或者在某些我不知道的情况下 - 也就是说,我在生产中看到少量崩溃,但不是在我正在测试它)【参考方案4】:
public class Dialog extends DialogFragment 

private DialogListener dialogListener;


public void setDialogListener(DialogListener dialogListener) 
    this.dialogListener = dialogListener;



@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
    view = inflater.inflate(R.layout.layout_dialog, null);
    return view;


@Override
public void onDismiss(DialogInterface dialog) 
    super.onDismiss(dialog);
    if (null != dialogListener) 
        dialogListener.onDismiss();
    


public interface DialogListener 
    void onDismiss();

在活动中 ...

  Dialog  dialog= new Dialog();
        dialog.setDialogListener(new Dialog.DialogListener() 
            @Override
            public void onDismiss() 
                Foo()..
            
        );

【讨论】:

【参考方案5】:

在构造对话框并正确存储在mDialog 之后getDialog() 可能返回null 的一个原因是在DialogFragment 上意外调用dismiss()

当调用dismiss() 时,它会将mDialog 字段重置为null,以便后续调用getDialog() 将返回null,而不是之前构造的对话框。

在我的例子中,dismiss() 被调用来处理DialogFragmentonActivityCreated() 方法中的错误情况/side-case。随后尝试使用来自onResume() 方法的getDialog() 返回null

也可以参考DialogFragment类的源码,具体是它的dismissInternal(boolean allowStateLoss)方法:

https://github.com/aosp-mirror/platform_frameworks_base/blob/pie-platform-release/core/java/android/app/DialogFragment.java

【讨论】:

以上是关于DialogFragment.getDialog 返回 null的主要内容,如果未能解决你的问题,请参考以下文章