使用导航组件将返回箭头添加到片段

Posted

技术标签:

【中文标题】使用导航组件将返回箭头添加到片段【英文标题】:Add back arrow to fragment with Navigation Component 【发布时间】:2020-08-07 08:00:00 【问题描述】:

我在一个应用程序上实现了一个基本的导航组件,该组件由一个 MainActivity 组成,该组件包含一个 Toolbar(我已添加它以具有后退箭头功能)和一个片段以 Fragment A 开头的容器。在这个片段中,我有一个按钮,它重定向到一个空白的 Fragment B

我可以使用 Navigation 组件从底部的 android 导航返回 fragment A(从 fragment B),但我想使用来自我添加的工具栏。 我实现了将 setSupportActionBar(findViewById(R.id.toolbar)) 放入 Main Activity(activity as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true) 的箭头Fragment B 上,但是当我点击它时它不会重定向到 Fragment A,因为(我想)后堆栈是空的。

MainActivity

class MainActivity : AppCompatActivity() 

override fun onCreate(savedInstanceState: Bundle?) 
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setSupportActionBar(findViewById(R.id.toolbar))

MainActivity xml

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_
    android:layout_
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    android:theme="?attr/actionBarTheme"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<androidx.fragment.app.FragmentContainerView
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_
    android:layout_
    app:defaultNavHost="true"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/toolbar"
    app:navGraph="@navigation/nav_graph" />

片段B

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
    super.onViewCreated(view, savedInstanceState)
    (activity as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)

添加此项以删除 styles.xml

中的默认工具栏
<item name="windowNoTitle">true</item>

FragmentB 中向上按钮不起作用 fragmentB with back not working

我想使用 导航组件 来做这件事,有什么想法吗?

谢谢。

【问题讨论】:

“在这个片段中,我有一个按钮可以重定向到空白片段 B”——您是否使用导航组件来执行此操作?你add the code that the docs call for了吗?换句话说,拥有minimal reproducible example 可以帮助我们帮助您解决问题! 我按照文档link 使用导航组件从片段 A 转到 B。谢谢!我将项目上传到回购并发布到问题:) 【参考方案1】:

感谢@MustafaKhaled,我可以在link 中找到正确的文档

我删除了fragmentB的setDisplayHomeAsUpEnabled(你不需要在这个fragment中添加任何东西)。

我离开,因为它是 styles.xml 的代码。

我的新MainActivity是这样的:

private lateinit var toolbar: Toolbar

override fun onCreate(savedInstanceState: Bundle?) 
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    toolbar = findViewById(R.id.toolbar)
    setupNavigation()


private fun setupNavigation() 
    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    val appBarConfiguration = AppBarConfiguration.Builder(navController.graph).build()
    toolbar.setupWithNavController(navController, appBarConfiguration)

按照这种方式,您可以通过 Navigation-UI 功能管理工具栏行为。


2020 年 4 月 28 日更新

有一种比这更简单的方法,它不需要工具栏,因为使用的是默认工具栏。

MainActivity

class MainActivity : AppCompatActivity() 
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var navController: NavController

override fun onCreate(savedInstanceState: Bundle?) 
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setupNavigation()


private fun setupNavigation() 
    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    navController = navHostFragment.navController
    appBarConfiguration = AppBarConfiguration.Builder(navController.graph).build()
    setupActionBarWithNavController(navController, appBarConfiguration)


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

activity_main.xml

<androidx.constraintlayout.widget.ConstraintLayout 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/fragment_container"
android:layout_
android:layout_>

<fragment
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_
    android:layout_
    app:defaultNavHost="true"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:navGraph="@navigation/nav_graph" />

而我的 styles.xml 文件就像默认的一样:

 <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

更新的回购link

【讨论】:

我不知道androidx.navigation.ui.setupWithNavController扩展方法,那是一个关键时刻,这解决了我的问题。谢谢!只是为了完成你的答案setupWithNavController只能用第一个参数调用,第二个参数有一个默认值AppBarConfiguration(navController.graph)【参考方案2】:

在你的 MainActivity

设置您的导航:

    private fun setupNavigation() 
    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment?
    navController = navHostFragment!!.navController
    appBarConfiguration = AppBarConfiguration.Builder(setOf(R.id.checklocation,R.id.questions,R.id.news,R.id.profile_tab)).build()
    NavigationUI.setupWithNavController(bottomNavigation,navController)
    NavigationUI.setupActionBarWithNavController(this,navController)

启用后退箭头并显示上一个目的地覆盖此功能

    override fun onSupportNavigateUp(): Boolean 
    return navController.navigateUp()

顺便说一下,使用带有底部导航的导航组件,我们不必配置您的工具栏,这将通过在您的 MainActivity 中添加上述功能来处理。

【讨论】:

bottomNavigation 有什么用?为什么不使用 appBarConfiguration?谢谢@MustafaKhaled 很抱歉,我无法理解您的问题。

以上是关于使用导航组件将返回箭头添加到片段的主要内容,如果未能解决你的问题,请参考以下文章

使用导航架构组件添加(而不是替换)片段

使用导航组件处理工具栏后退按钮

如何通过后退按钮(箭头)将活动导航到片段?

使用 ShellContent xamarin 表单时添加导航返回箭头

导航组件 - BottomNavigationView - 返回时不要保留 startDestination 片段

Android导航组件:如何保存片段状态