在show()

时间:2018-08-09 18:54:33

标签: android illegalstateexception dialogfragment

我正在处理带有许多对话框的android应用程序,所有这些对话框都扩展了一个自定义类“ DialogFragmentBase”,该类扩展了库的“ DialogFragment”。所有活动都使用DialogFragmentBase中覆盖的show()方法。

如果父活动处于后台(如接听电话),我想避免显示对话框,因为这会导致非法的StatEexception,但与此同时,我也不想保护每次活动中的每个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。另外,由于尚未调用onAttach,因此getActivity()返回null。

谢谢!

2 个答案:

答案 0 :(得分:0)

也许您可以在对话框基类中创建一个新方法:

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

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

答案 1 :(得分:0)

support library FragmentManager有一个isStateSaved() method。根据确切的要求,您可以利用它来检查显示对话框是否“安全”:

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

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