从特定片段导航到另一个片段后无法使用后退按钮返回
Can't go back using the back button after navigating from a specific fragment to another
在我的应用程序中有这样的导航流程
AuthFragment --> SellerMainScreenFragment -----> pay_nav_graph (Nested Graph)
|
|----> CreditFragment---------
| |
|----> CreditAddFragment <---|
|
|-------> TransactionResultFragment
现在,当应用程序尝试从 SellerMainScreenFragment
导航到 CreditAddFragment
时,一切正常,在后一个片段中按下后退按钮后,应用程序 returns 到前者.导航代码为
adapter.wasAddBalPressed.observe(viewLifecycleOwner, Observer {
if (it != NO_VAL)
findNavController().navigate(SellerMainScreenFragmentDirections.actionSellerListScreenFragmentToCreditAddFragment(it))
})
但是当应用程序从 CreditFragment
导航到 CreditAddFragment
时,按下 CreditAddFragment
中的后退按钮后,应用程序不会 return 到上一个片段.代码如下:
val action = CreditFragmentDirections.actionCreditFragmentToCreditAddFragment(viewModel.userSellerPhoneNo)
findNavController().navigate(action)
我试过像这样在 OnBackPressedDispatcher
上设置自定义 onBackPressedCallback
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
findNavController().popBackStack()
remove()
}
但即便如此,如果它是 CreditFragment
,它也不会 return 到前一个片段,但在 SellerMainScreenFragment
的情况下,它会按预期工作。
我也正确设置了 NavHostFragment
中的 app:defaultNavHost = true
。
此时我已经尝试清理项目、使缓存无效、冷启动模拟器并尝试调试,但即便如此我也找不到任何可疑的东西。
所以如果有人能帮忙,请尝试so.Thanks。
编辑-1 :-
这是我目前在应用程序中使用的导航xml文件
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_nav_host_fragment"
app:startDestination="@id/authFragment">
<fragment
android:id="@+id/authFragment"
android:name="com.example.paylater.ui.AuthFragment"
android:label="AuthFragment"
tools:layout="@layout/fragment_auth">
<action
android:id="@+id/action_authFragment_to_sellerListScreenFragment"
app:destination="@id/sellerListScreenFragment"
app:popUpTo="@id/authFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/sellerListScreenFragment"
android:name="com.example.paylater.ui.SellerMainScreenFragment"
android:label="SellerListScreenFragment"
tools:layout="@layout/fragment_main_screen">
<action
android:id="@+id/listFragment_to_creditFragment"
app:destination="@id/creditFragment" />
<action
android:id="@+id/action_sellerListScreenFragment_to_pay_nav_graph"
app:destination="@id/pay_nav_graph" />
<action
android:id="@+id/action_sellerListScreenFragment_to_creditAddFragment"
app:destination="@id/creditAddFragment" />
</fragment>
<fragment
android:id="@+id/creditFragment"
android:name="com.example.paylater.ui.CreditFragment"
android:label="CreditFragment"
tools:layout="@layout/fragment_credit_enter_no">
<!--<action
android:id="@+id/action_creditFragment_self"
app:destination="@id/creditFragment" />-->
<action
android:id="@+id/action_creditFragment_to_creditAddFragment"
app:destination="@id/creditAddFragment" />
</fragment>
<fragment
android:id="@+id/creditAddFragment"
android:name="com.example.paylater.ui.CreditAddFragment"
android:label="CreditAddFragment"
tools:layout="@layout/fragment_credit_add">
<action
android:id="@+id/action_creditAddFragment_self"
app:destination="@id/creditAddFragment" />
<action
android:id="@+id/action_creditAddFragment_to_transactionResultFragment"
app:destination="@id/transactionResultFragment" />
<argument
android:name="sellerPhoneNo"
app:argType="string" />
</fragment>
<fragment
android:id="@+id/transactionResultFragment"
android:name="com.example.paylater.ui.TransactionResultFragment"
android:label="TransactionResultFragment"
tools:layout="@layout/fragment_transaction_result">
<action
android:id="@+id/action_transactionResultFragment_self"
app:destination="@id/transactionResultFragment" />
<argument
android:name="sellerPhoneNo"
app:argType="string" />
</fragment>
<action
android:id="@+id/action_global_sellerListScreenFragment"
app:destination="@id/sellerListScreenFragment" />
<navigation
android:id="@+id/pay_nav_graph"
app:startDestination="@id/payFragment">
<argument
android:name="sellerPhoneNo"
app:argType="string" />
<fragment
android:id="@+id/payFragment"
android:name="com.example.paylater.ui.PayFragment"
android:label="PayFragment">
<argument
android:name="sellerPhoneNo"
app:argType="string" />
<action
android:id="@+id/action_payFragment_to_processPaymentFragment"
app:destination="@id/processPaymentFragment" />
<action
android:id="@+id/action_payFragment_self"
app:destination="@id/payFragment" />
</fragment>
<fragment
android:id="@+id/processPaymentFragment"
android:name="com.example.paylater.ui.ProcessPaymentFragment"
android:label="ProcessPaymentFragment" />
</navigation>
</navigation>
Edit-2:
即使在显式调用
之后
findNavController().popBackStack(R.id.creditFragment, false)
在 onBackPressedCallback
中,它仍然没有 return 到前一个片段 (CreditFragment
)
所以基本上应用程序正在观察 CreditFragment
中的 MediatorLiveData
,当它的值改变导航到 CreditAddFragment
时发生了。
但由于某些原因,MediatorLiveData
的值在导航到下一个片段时保持不变,按下后退按钮后,应用导航到上一个片段,但随后 立即再次导航到CreditAddFragment
,导致它看起来好像没有发生后退导航。
我在@MaryJane 建议查看 backstack 行为后,将 Log
语句放入两个片段的 onViewCreated()
中时发现了这一点。
然后我才看到这种奇怪的行为。非常感谢@MaryJane 帮我解决了这个问题,对提出这样问题的大家表示抱歉。
在我的应用程序中有这样的导航流程
AuthFragment --> SellerMainScreenFragment -----> pay_nav_graph (Nested Graph)
|
|----> CreditFragment---------
| |
|----> CreditAddFragment <---|
|
|-------> TransactionResultFragment
现在,当应用程序尝试从 SellerMainScreenFragment
导航到 CreditAddFragment
时,一切正常,在后一个片段中按下后退按钮后,应用程序 returns 到前者.导航代码为
adapter.wasAddBalPressed.observe(viewLifecycleOwner, Observer {
if (it != NO_VAL)
findNavController().navigate(SellerMainScreenFragmentDirections.actionSellerListScreenFragmentToCreditAddFragment(it))
})
但是当应用程序从 CreditFragment
导航到 CreditAddFragment
时,按下 CreditAddFragment
中的后退按钮后,应用程序不会 return 到上一个片段.代码如下:
val action = CreditFragmentDirections.actionCreditFragmentToCreditAddFragment(viewModel.userSellerPhoneNo)
findNavController().navigate(action)
我试过像这样在 OnBackPressedDispatcher
上设置自定义 onBackPressedCallback
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
findNavController().popBackStack()
remove()
}
但即便如此,如果它是 CreditFragment
,它也不会 return 到前一个片段,但在 SellerMainScreenFragment
的情况下,它会按预期工作。
我也正确设置了 NavHostFragment
中的 app:defaultNavHost = true
。
此时我已经尝试清理项目、使缓存无效、冷启动模拟器并尝试调试,但即便如此我也找不到任何可疑的东西。
所以如果有人能帮忙,请尝试so.Thanks。
编辑-1 :-
这是我目前在应用程序中使用的导航xml文件
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_nav_host_fragment"
app:startDestination="@id/authFragment">
<fragment
android:id="@+id/authFragment"
android:name="com.example.paylater.ui.AuthFragment"
android:label="AuthFragment"
tools:layout="@layout/fragment_auth">
<action
android:id="@+id/action_authFragment_to_sellerListScreenFragment"
app:destination="@id/sellerListScreenFragment"
app:popUpTo="@id/authFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/sellerListScreenFragment"
android:name="com.example.paylater.ui.SellerMainScreenFragment"
android:label="SellerListScreenFragment"
tools:layout="@layout/fragment_main_screen">
<action
android:id="@+id/listFragment_to_creditFragment"
app:destination="@id/creditFragment" />
<action
android:id="@+id/action_sellerListScreenFragment_to_pay_nav_graph"
app:destination="@id/pay_nav_graph" />
<action
android:id="@+id/action_sellerListScreenFragment_to_creditAddFragment"
app:destination="@id/creditAddFragment" />
</fragment>
<fragment
android:id="@+id/creditFragment"
android:name="com.example.paylater.ui.CreditFragment"
android:label="CreditFragment"
tools:layout="@layout/fragment_credit_enter_no">
<!--<action
android:id="@+id/action_creditFragment_self"
app:destination="@id/creditFragment" />-->
<action
android:id="@+id/action_creditFragment_to_creditAddFragment"
app:destination="@id/creditAddFragment" />
</fragment>
<fragment
android:id="@+id/creditAddFragment"
android:name="com.example.paylater.ui.CreditAddFragment"
android:label="CreditAddFragment"
tools:layout="@layout/fragment_credit_add">
<action
android:id="@+id/action_creditAddFragment_self"
app:destination="@id/creditAddFragment" />
<action
android:id="@+id/action_creditAddFragment_to_transactionResultFragment"
app:destination="@id/transactionResultFragment" />
<argument
android:name="sellerPhoneNo"
app:argType="string" />
</fragment>
<fragment
android:id="@+id/transactionResultFragment"
android:name="com.example.paylater.ui.TransactionResultFragment"
android:label="TransactionResultFragment"
tools:layout="@layout/fragment_transaction_result">
<action
android:id="@+id/action_transactionResultFragment_self"
app:destination="@id/transactionResultFragment" />
<argument
android:name="sellerPhoneNo"
app:argType="string" />
</fragment>
<action
android:id="@+id/action_global_sellerListScreenFragment"
app:destination="@id/sellerListScreenFragment" />
<navigation
android:id="@+id/pay_nav_graph"
app:startDestination="@id/payFragment">
<argument
android:name="sellerPhoneNo"
app:argType="string" />
<fragment
android:id="@+id/payFragment"
android:name="com.example.paylater.ui.PayFragment"
android:label="PayFragment">
<argument
android:name="sellerPhoneNo"
app:argType="string" />
<action
android:id="@+id/action_payFragment_to_processPaymentFragment"
app:destination="@id/processPaymentFragment" />
<action
android:id="@+id/action_payFragment_self"
app:destination="@id/payFragment" />
</fragment>
<fragment
android:id="@+id/processPaymentFragment"
android:name="com.example.paylater.ui.ProcessPaymentFragment"
android:label="ProcessPaymentFragment" />
</navigation>
</navigation>
Edit-2: 即使在显式调用
之后findNavController().popBackStack(R.id.creditFragment, false)
在 onBackPressedCallback
中,它仍然没有 return 到前一个片段 (CreditFragment
)
所以基本上应用程序正在观察 CreditFragment
中的 MediatorLiveData
,当它的值改变导航到 CreditAddFragment
时发生了。
但由于某些原因,MediatorLiveData
的值在导航到下一个片段时保持不变,按下后退按钮后,应用导航到上一个片段,但随后 立即再次导航到CreditAddFragment
,导致它看起来好像没有发生后退导航。
我在@MaryJane 建议查看 backstack 行为后,将 Log
语句放入两个片段的 onViewCreated()
中时发现了这一点。
然后我才看到这种奇怪的行为。非常感谢@MaryJane 帮我解决了这个问题,对提出这样问题的大家表示抱歉。