【问题标题】:Can't go back using the back button after navigating from a specific fragment to another从特定片段导航到另一个片段后无法使用后退按钮返回
【发布时间】:2020-08-14 12:24:59
【问题描述】:

在我的应用中有这样的导航流程

AuthFragment --> SellerMainScreenFragment -----> pay_nav_graph (Nested Graph)
                                    |
                                    |----> CreditFragment---------
                                    |                            |
                                    |----> CreditAddFragment <---|
                                                            |
                                                            |-------> TransactionResultFragment

现在,当应用程序尝试从 SellerMainScreenFragment 导航到 CreditAddFragment 时,一切正常,按下后一个片段中的后退按钮后,应用程序返回到前一个。导航代码是

adapter.wasAddBalPressed.observe(viewLifecycleOwner, Observer {
  if (it != NO_VAL)
     findNavController().navigate(SellerMainScreenFragmentDirections.actionSellerListScreenFragmentToCreditAddFragment(it))
})

但是当应用程序从CreditFragment 导航到CreditAddFragment 时,在按下CreditAddFragment 中的后退按钮时,应用程序不会返回到上一个片段。代码如下:

val action = CreditFragmentDirections.actionCreditFragmentToCreditAddFragment(viewModel.userSellerPhoneNo)
findNavController().navigate(action)

我尝试在OnBackPressedDispatcher 上设置自定义onBackPressedCallback,就像这样

requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
    findNavController().popBackStack()
    remove()
}

但即便如此,如果它是CreditFragment,它也不会返回到前一个片段,但在SellerMainScreenFragment 的情况下,它会按预期工作。

我还在NavHostFragment 中正确设置了app:defaultNavHost = true

此时我已尝试清理项目、使缓存无效、冷启动模拟器并尝试调试,但即便如此我也找不到任何可疑之处。

所以如果有人可以帮忙,请尝试这样做。谢谢。

Edit-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中,仍然没有返回到上一个片段(CreditFragment

【问题讨论】:

  • 那么如果返回按钮没有转到CreditFragment,它会去哪里?
  • 尝试使用这行代码:findNavController().navigateUp(),而不是使用popBackStack。并且您可以使用特定的 id 传递您希望您进入后台堆栈的布局 id。
  • @MaryJane 什么都没有发生,它只是停留在同一个片段上,无论是否。我按下它的次数。
  • 你能给我们看看你的导航图 XML
  • 好的。如果您可以将其添加到描述中,打印您的背钉列表可能会有所帮助。如果你也可以包含导航图。

标签: android kotlin android-fragments android-architecture-navigation


【解决方案1】:

所以基本上该应用程序在CreditFragment 中观察到MediatorLiveData,当它的值更改为CreditAddFragment 的导航发生时。

但由于某种原因,MediatorLiveData 的值在导航到下一个片段时保持不变,并且在按下后退按钮时,应用导航到上一个片段,但随后 再次导航立即到CreditAddFragment,导致它看起来好像没有发生后退导航。

我在 @MaryJane 建议查看 backstack 行为之后,将 Log 语句放在两个片段的 onViewCreated() 中时发现了这一点。

然后我才看到这种奇怪的行为。非常感谢@MaryJane 帮助我解决了这个问题,也很抱歉大家提出这样的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-03
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多