使用 NavigationComponent 在另一个 DialogFragment 的 navBackStackEntry 观察者结果中显示 DialogFragment

Show DialogFragment in navBackStackEntry observer result of another DialogFragment using NavigationComponent

这是我的片段的onViewCreated

@Override
public void onViewCreated(@NonNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    NavHostFragment navHostFragment = (NavHostFragment) requireActivity().getSupportFragmentManager().findFragmentById(R.id.container);

    binding.button.setOnClickListener(v -> {
        if (navHostFragment != null) {
            NavController navController0 = navHostFragment.getNavController();

            navController0.navigate(MyFragmentDirections.actionMyFragmentToMessageDialog(
                    false,
                    R.drawable.ic_success,
                    "My Message 1",
                    R.string.yes,
                    R.string.no,
                    R.drawable.circle_yellow
            ));
        }
    });

    if (navHostFragment != null) {
        NavController navController1 = navHostFragment.getNavController();
        NavBackStackEntry navBackStackEntry = navController1.getCurrentBackStackEntry();
        if (navBackStackEntry != null) {
            SavedStateHandle savedStateHandle = navBackStackEntry.getSavedStateHandle();
            MutableLiveData<String> liveData = savedStateHandle.getLiveData(Const.DIALOG_BTN_DATA);
            liveData.observe(getViewLifecycleOwner(), btnData -> {
                //            savedStateHandle.remove(Const.DIALOG_BTN_DATA);

                if (btnData.equals("btn_right")) {
                    Log.i(TAG, "Dialog Btn Clicked -----> btn_right");
                    NavController navController2 = navHostFragment.getNavController();
                    navController2.navigate(MyFragmentDirections.actionMyFragmentToMessageDialog(
                            false,
                            R.drawable.ic_success,
                            "My Message 2",
                            R.string.yes,
                            R.string.no,
                            R.drawable.circle_red
                    ));

                } else {
                    // Do Some Stuff
                }
            });
        }
    }
}

这是对话框的按钮 onClickListener

binding.btnRight.setOnClickListener(v -> {
    NavHostFragment navHostFragment = (NavHostFragment) requireActivity().getSupportFragmentManager().findFragmentById(R.id.container);
    if (navHostFragment != null) {
        NavController navController = navHostFragment.getNavController();
        NavBackStackEntry navBackStackEntry = navController.getPreviousBackStackEntry();
        if (navBackStackEntry != null) {
            SavedStateHandle savedStateHandle = navBackStackEntry.getSavedStateHandle();
            savedStateHandle.set(Const.DIALOG_BTN_DATA, "btn_right");
        }
        navController.navigateUp();
    }
});

我需要在收到另一个 DialogFragment 结果时显示 DialogFragment,但应用程序在语句 navController2.navigate(MyFragmentDirections.actionMyFragmentToMessageDialog... 中崩溃并且出现以下错误:

java.lang.IllegalArgumentException: Navigation action/destination com.example.app:id/action_myFragment_to_messageDialog cannot be found from the current destination

任何人都可以帮助我解决问题并在使用 NavigationComponent 的另一个 DialogFragment 的 navBackStackEntry 观察器结果中显示 DialogFragment 吗?

您的问题与 navController 的使用无关。您可以在 Navigation Component documents.

中找到它的定义

所以我避免描述它们并想专注于您的代码。

Action XY 表示您只想从 X 导航到 Y。换句话说,back-stack 中的最后 entry/destination 必须是 X.

1.

在显示 MyFragment 的情况下,返回堆栈如下:

[ MyFragment ]

并且当您调用 getSavedStateHandle() 并开始观察它时 savedState 意味着您正在观察 MyFragment 的 savedState。

2.

当您想在按钮点击侦听器中使用 "My Message 1" 启动对话框时,返回堆栈仍然是:

[ MyFragment ]

启动对话框后如下所示:

[ MyFragment, MessageDialog ]

因此,当您在对话框中 getPreviousBackStackEntry 时,它会引用 MyFragment 并在 MyFragment 的 savedState 上成功 set(Const.DIALOG_BTN_DATA, "btn_right")

此时 MyFragment 中的观察者将被触发并尝试通过 actionMyFragmentToMessageDialog"My Message 2" 启动对话。

此操作从 MyFragmentMessageDialog,但返回堆栈中的最新条目是 MessageDialog(不是 MyFragment)。轰

navController.navigateUp() 永远不会调用弹出对话框 :D


show DialogFragment in navBackStackEntry observer result of another DialogFragment using NavigationComponent?

您的问题来自本地操作的限制。因此,您应该通过 destination-ids 或 deeplinks 或更好的导航方式 GlobalActions 提供安全参数设施。

我建议在这种情况下采取全球行动:

<action
    android:id="@+id/action_global_messageDialog"
    app:destination="@id/messageDialog" />
navController2.navigate(
    MyGraphDirections.actionGlobalMessageDialog(
        false,
        R.drawable.ic_success,
        "My Message 2"
        R.string.yes,
        R.string.no,
        R.drawable.circle_red
    ));