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

标签 java android android-dialogfragment android-architecture-navigation

这是我的 fragment 的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 中找到它的定义。 .

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

操作 XY意味着你想导航到 Y仅来自 X .换句话说,back-stack 中的最后一个条目/目的地必须是 X .

1.

在你的情况下 MyFragment显示后,返回堆栈是这样的:

[ MyFragment ]

当您调用 getSavedStateHandle() 时并开始观察它的 savedState意味着你正在观察 MyFragment的保存状态。

2.

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

[ MyFragment ]

启动对话框后如下所示:

[ MyFragment, MessageDialog ]

所以当你getPreviousBackStackEntry在对话框中,它指的是MyFragment并成功set(Const.DIALOG_BTN_DATA, "btn_right")MyFragment的保存状态。

此时观察者在MyFragment将被触发并尝试通过 actionMyFragmentToMessageDialog 启动对话框与 "My Message 2" .

这个 Action 来自MyFragmentMessageDialog但 back-stack 中的最新条目是 MessageDialog (不是我的 fragment )。轰轰

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


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

您的问题来自本地操作的限制。所以你应该通过 destination-id 导航s 或 deeplink s 或更好的一个是 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
    ));

关于java - 使用 NavigationComponent 在另一个 DialogFragment 的 navBackStackEntry 观察者结果中显示 DialogFragment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67658972/

相关文章:

java - SpringBoot从2.1.1升级到2.1.2报错

java - Android 找不到类 java.awt.datatransfer.StringSelection?尝试将字符串放在剪贴板上

java - 在 Android 中获取 Facebook 页面状态更新列表

Android Dark 主题反转矢量绘图的颜色

java - 如何在 DialogFragment 的 textView 中 setText()

java - 在 DialogFragment 中膨胀类 fragment 时出错

android - 除了使用 Intent 启动 FragmentActivity 之外,还有其他方法可以调用 FragmentActivity 中的方法吗?

java - apache common vfs和mercurial的集成

Java 错误 : "Exception in thread "main"java. util.InputMismatchException”

android - 除了使用 isPressed() 方法还有其他方法吗?