使用 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 X
到 Y
表示您只想从 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"
启动对话。
此操作从 MyFragment
到 MessageDialog
,但返回堆栈中的最新条目是 MessageDialog
(不是 MyFragment)。轰
和 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
));
这是我的片段的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 X
到 Y
表示您只想从 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"
启动对话。
此操作从 MyFragment
到 MessageDialog
,但返回堆栈中的最新条目是 MessageDialog
(不是 MyFragment)。轰
和 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
));