由于起始目的地,工具栏返回按钮被隐藏

3

背景

我试图使用每个模块一个活动的方式,其中每个活动都有自己的导航图。因此,导航从一个动态特性模块中的活动到另一个动态特性模块中的另一个活动。

Feature1/ActivityA -> Feature2/ActivityB

ActivityA只需调用基本的startActivity方法来启动ActivityB。

问题

由于ActivityB在技术上具有其片段作为起始目标。即使我将ActivityA放在我的后台堆栈中,它也不会显示返回按钮。有没有办法解决这个问题?

PS:由于ActivityAActivityB位于2个单独的模块中,我避免将它们放在一个图形下。对于活动转换,我只是通过创建使用classNameintent来调用startActivity

更新 - 即使我使用nav控制器从ActivityA的片段导航到ActivityB,问题仍然存在。

ActivityB.xml

</layout>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/main_toolbar"
            app:navigationIcon="@drawable/ic_back"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:title="@string/title" />

        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/host_container"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            app:defaultNavHost="true"
            app:navGraph="@navigation/landing_graph" />
    </LinearLayout>

</layout>

ActivityB.kt

internal class ActivityB : AppCompatActivity() {

    private var navController : NavController? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val toolbar = binding.mainToolbar
        navController = supportFragmentManager.findFragmentById(R.id.host_container) as NavHostFragment).navController
        setSupportActionBar(toolbar)
        toolbar.setNavigationOnClickListener { onBackPressed() }
        toolbar.setupWithNavController(navController)
    }

    override fun onSupportNavigateUp(): Boolean {
        return navController.navigateUp() || super.onSupportNavigateUp()
    }
}

landing_graph.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    app:startDestination="@id/blankFragment">
    <fragment
        android:id="@+id/blankFragment"
        android:name="com.example.cashdog.cashdog.BlankFragment"
        android:label="Blank"
        tools:layout="@layout/fragment_blank" />

    <fragment
        android:id="@+id/blankFragment2"
        android:name="com.example.cashdog.cashdog.BlankFragment2"
        android:label="Blank"
        tools:layout="@layout/fragment_blank_2" />
</navigation>

你使用单独的活动,是否有特别的原因?因为导航在单个图中专门支持动态特性模块 - ianhanniballake
使用动态特性模块,不支持深链接,这是主要原因。 - user3354265
1个回答

7
根据AppBarConfiguration指南,如果您希望在所有目标页面上(包括起始页面)显示返回按钮,则应使用传入顶级目标列表的AppBarConfiguration构造函数。通过传递空集合,每个目标页面都将显示返回按钮。
因此,您的ActivityB应该是:
internal class ActivityB : AppCompatActivity() {

    private var navController : NavController? = null
    private val appBarConfiguration = AppBarConfiguration(emptySet())

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val toolbar = binding.mainToolbar
        navController = supportFragmentManager.findFragmentById(R.id.host_container) as NavHostFragment).navController
        setSupportActionBar(toolbar)
        // You must always use setupActionBarWithNavController
        // when using setSupportActionBar()
        setupActionBarWithNavController(navController, appBarConfiguration)
    }

    override fun onSupportNavigateUp(): Boolean {
        return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
    }
}

1
传递 emptySet 的一个问题是,当加载 startDestination 碎片时,开始目标的 android:label 不会第一次被选中。唯一的解决方法是在加载 startDestination Fragment 时从 startDestination Fragment 中调用 setTitle - user3354265
顶级目的地集合不用于确定标签设置的行为(对于每个目的地,它总是被设置)。听起来你还有其他问题。 - ianhanniballake
如果我不传递 emptySet,那么标题将显示出来,但是没有返回按钮,因为它从导航图中选择了 android:label,但是当我传递 emptySet 时,它会选择我的应用程序名称作为标签。 - user3354265
就我个人而言,如果您在图形中使用android:label,我不认为您首先需要在工具栏上使用app:title="@string/title"。即使如此,在源代码中,标题也会无条件地设置,无论您传递什么集合。 - ianhanniballake
我正在动态更改title,即尝试将一个功能模块保持在一个活动中。因此,单个活动可以具有不同的导航图(也称为不同的起始目的地)。我将通过片段使用setTitle作为解决方法。非常感谢您的帮助,真的很感激。 - user3354265
我认为 emptyset 解决了这个问题。谢谢。 - kondal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接