在 show() 之前获取 DialogFragment 子类中的父 activity

Get parent activity in DialogFragment subclass before show()

我正在开发一个包含许多对话框的 android 应用程序,所有这些对话框都扩展了一个名为 "DialogFragmentBase" 的自定义 class,它扩展了库的 "DialogFragment"。所有活动都使用在 DialogFragmentBase 中覆盖的 show() 方法。

如果父 activity 处于后台(如接收 phone 调用),我想阻止显示对话框,因为这会导致 illegalStatEexception,但同时我不会想要保护应用程序中的每个 show() 调用:

if(getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED))

所以我想在 DialogFragmentBase 中做这样的事情:

@Override
public void show(FragmentManager manager, String tag){

    List<Fragment> fragments = manager.getFragments();
    if(fragments != null && fragments.size() > 0){
        FragmentActivity activity = fragments.get(fragments.size()-1).getActivity();
        if(activity != null && activity.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)){
            super.show(manager, tag);
        }
    }
}

所以我的问题是:像这样访问上一个片段是否被认为是一种不好的做法?它确实有效……但我记得在某处读到片段不应相互通信。如果这确实是一种不好的做法,那么什么是可以在 DialogFragmentBase 中实现的更好的解决方案(避免在任何地方添加守卫)。

注意:我尝试了 here 中描述的 onSaveInstanceState 解决方案,但由于尚未显示 DialogFragment,因此此时不会调用 onSaveInstanceState。 getActivity() returns null 因为此时还没有调用 onAttach。

谢谢!

也许你可以在你的对话库中创建一个新方法class:

public void showIfResumed(FragmentActivity activity, String tag) {
    if (/* your check here, e.g. activity.getLifecycle()...  */) {
        show(activity.getSupportFragmentManager(), tag);
    }
}

然后,在您的活动中,您可以调用 showIfResumed(this, TAG) 而不是调用 show(getSupportFragmentManager(), TAG)。您仍然需要将对 show() 的每次调用更改为对 showIfResumed() 的调用,但这会大大减少代码重复。

support library FragmentManager has an isStateSaved() method。根据您的具体要求,您可以利用它来检查它是否 "safe" 来显示您的对话框:

@Override
public void show(FragmentManager manager, String tag) {
    if (!manager.isStateSaved()) {
        super.show(manager, tag);
    }
}

请注意,上面的实现与使用 commitAllowingStateLoss() 比较相似,因为在某些情况下您会默默地无法显示对话框。但这也许可以满足您的要求。