DialogFragment的dismiss()方法无法弹出回退栈

11

我有一个简单的DialogFragment,当退出时会调用dismiss方法,根据文档:

public void dismiss()

关闭此片段及其对话框。如果片段已添加到   回退堆栈,则将弹出所有回退堆栈状态,直到包括此条目为止。 否则,将提交新事务以删除该片段。

然而,我发现在调用dismiss()后,该片段仍然在后退堆栈中,因此我必须点击返回按钮来清除它。 有人知道为什么吗?

这是我的代码:

public void onCreate(Bundle b) {
        super.onCreate(b);
        setContentView(R.layout.test_layout);

        class MyDialogFragment extends DialogFragment implements OnClickListener{

            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

                View v = inflater.inflate(R.layout.hello_world, container, false);

                Button b = (Button)v.findViewById(R.id.btn);
                b.setOnClickListener(this);

                return v;
            }

            @Override
            public void onClick(View v) {
                dismiss();
            }
        }

        getFragmentManager().beginTransaction().add(android.R.id.content, new MyDialogFragment(), "test").addToBackStack("b").commit();
    }

    @Override
    public void onBackPressed() {
        if (getFragmentManager().getBackStackEntryCount() > 0 ){
            getFragmentManager().popBackStack();
        } else {
            super.onBackPressed();
        }
    }
}

我还发现,如果我不覆盖 onBackPressed() 方法,无论我在活动中添加了多少个片段,返回按钮始终会立即退出活动,根本没有作用。


我认为文档中所述的行为发生在将片段作为实际对话框添加时,通过使用“show()”方法,而不是像您在代码中所做的那样将其视为普通片段。返回按钮也应该正常工作,除非您正在做一些可疑的事情。 - user
你是使用 android.app.DialogFragment 还是 android.support.v4.app.DialogFragment?你找到了解决这个问题的方法吗? - Ibrahim Disouki
3个回答

7

3

创建 DialogFragment 的方式不正确。

绝对不要使用 FragmentManager 来显示 DialogFragment。有一种方法叫做show(FragmentTransaction, String)。

在 Java 中:

MyDialogFragment mDialogFragment = new MyDialogFragment();
mDialogFragment.show(getFragmentManager(), "MyDialogFragment");

另一方面,要关闭对话框,只需执行以下操作:

mDialogFragment.dismiss()

我希望强调的另一个问题是MyDialogFragment类在onCreate方法中被定义为内部类:'( 如果需要,请在方法外面或另外一个文件中定义该类 :)

祝一切顺利!


0
dismiss()
findNavController().navigate(FirstBottomSheetDialogDirections.actionFirstSheetToSecondSheet())

这段代码总是做错事情:dismiss() 是一个异步操作,它不会立即解除任何东西。这与 navigate() 不同,后者会立即更新 NavController 的状态,在前一个目标对话框的顶部堆叠新的对话框目标。

这意味着当异步 dismiss 实际发生时,它会正确地删除对话框,并且由于它是一个导航堆栈,它会删除其上面的所有内容 - 包括您的第二个对话框。然而,由于 DialogFragmentNavigator 中的一个错误,我们实际上没有解除那个第二个对话框,这就是为什么它看起来可以工作,尽管实际上已经内部不同步(从而导致后来崩溃)。

弹出一个目标并立即作为原子操作导航到新目标的正确方法是使用 popUpTo 和 popUpToInclusive。因此,您可以通过删除对 dismiss() 的调用并更新操作以在 navigate 调用中弹出第一个对话框来修复示例应用程序:

<action
    android:id="@+id/action_firstSheet_to_secondSheet"
    app:destination="@id/secondSheet"
    app:popUpTo="@id/firstSheet"
    app:popUpToInclusive="true"/>

这样做可以正确地将后退栈中的第一个对话框弹出,然后导航到新的对话框目的地。

请参考此链接:https://issuetracker.google.com/issues/191073055


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接