简体   繁体   English

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

[英]Handle physical back button in Navigation Component with Toolbar

I have a simple proof of concept app that contains only 2 fragments: MainFragment and RepositoryFragment and 1 activity: MainActivity我有一个简单的概念证明应用程序,它只包含 2 个片段: MainFragmentRepositoryFragment以及 1 个活动: MainActivity

Here's my nav_graph这是我的nav_graph

<?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/nav_graph"
    app:startDestination="@id/id_main">

    <fragment
        android:id="@+id/id_main"
        android:name="com.repofetcher.main.view.MainFragment"
        android:label="@string/app_name"
        tools:layout="@layout/main_fragment">
        <action
            android:id="@+id/action_mainfragment_to_repositoryfragment"
            app:destination="@id/id_repo"
            app:popUpTo="@id/id_main"
            app:popUpToInclusive="true"/>
    </fragment>

    <fragment
        android:id="@+id/id_repo"
        android:name="com.repofetcher.repo.view.RepositoryFragment"
        android:label="{arg_repo_name}"
        tools:layout="@layout/repository_fragment">
        <argument
            android:name="arg_repo_name"
            app:argType="string"
            android:defaultValue="@null"
            app:nullable="true" />
    </fragment>

</navigation>

MainActivity:主要活动:

    private lateinit var navController: NavController

    override fun onCreate(savedInstanceState: Bundle?) {
        (application as RepoFetcherApplication).appComponent.mainComponent().create().inject(this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)
        navController = findNavController(R.id.nav_host_fragment)
        setupActionBarWithNavController(navController)
    }

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

Main activity's layout:主要活动的布局:

<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".main.view.MainActivity">

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        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" />

</androidx.constraintlayout.widget.ConstraintLayout>

This is the part that navigates from MainFragment to RepositoryFragment这是从MainFragment导航到RepositoryFragment的部分

    private fun navToRepositoryFragment(name: String) {
        findNavController().navigate(MainFragmentDirections.actionMainfragmentToRepositoryfragment(argRepoName = name))
    }

RepositoryFragment:存储库片段:

 override fun onCreate(savedInstanceState: Bundle?) {
        (requireActivity().application as RepoFetcherApplication).appComponent.repoComponent().create().inject(this)
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        dataBinding = DataBindingUtil.inflate(inflater, R.layout.repository_fragment, container, false)
        dataBinding.lifecycleOwner = this
        viewModel = ViewModelProvider(this, viewModelProviderFactory).get(RepositoryViewModel::class.java)
        dataBinding.viewModel = viewModel
        return dataBinding.root
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel.getRepository(args.argRepoName)
    }

Ideally, I would like to achieve these navigations:理想情况下,我想实现这些导航:

navigating from MainFragment to RepositoryFragment , then by clicking either the back button on the Toolbar or on the device, it should navigate back to the MainFragment .MainFragment导航到RepositoryFragment ,然后通过单击Toolbar或设备上的后退按钮,它应该导航回MainFragment

However in my case, only the back button on the toolbar will work as intended.但是在我的情况下,只有工具栏上的后退按钮才能按预期工作。 The back button on the device will directly quit the app.设备上的后退按钮将直接退出应用程序。

I wonder what I'm missing in the code?我想知道我在代码中缺少什么?

Update更新

One of the real problem behind this question is I used livedata for a single event (to handle the click event in order to navigate to RepositoryFragment ).这个问题背后的真正问题之一是我将 livedata 用于单个事件(处理单击事件以导航到RepositoryFragment )。

So after taking a look at this article: https://proandroiddev.com/livedata-with-single-events-2395dea972a8所以看了这篇文章之后: https://proandroiddev.com/livedata-with-single-events-2395dea972a8

with solution @GabrieleMariotti provided and got the problem solved.提供@GabrieleMariotti 解决方案并解决了问题。

I would like to thank @GabrieleMariotti who helped me with great patient.我要感谢@GabrieleMariotti,他以极大的耐心帮助了我。

Remove the app:popUpTo="@id/id_main" and app:popUpToInclusive="true in your action :删除app:popUpTo="@id/id_main"app:popUpToInclusive="true在您的action中:

    <action
        android:id="@+id/action_mainfragment_to_repositoryfragment"
        app:destination="@id/nav_gallery"
        />

In your onCreate method use:在您的onCreate方法中使用:

    appBarConfiguration = AppBarConfiguration(navController.graph)
    setupActionBarWithNavController(navController, appBarConfiguration)

and in your onSupportNavigateUp method:并在您的onSupportNavigateUp方法中:

override fun onSupportNavigateUp(): Boolean {
    val navController = findNavController(R.id.nav_host_fragment)
    return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用导航组件处理工具栏后退按钮 - Handle Toolbar back button with Navigation component Android 架构组件导航:工具栏后退按钮丢失,后退不起作用 - Android architecture component navigation: toolbar back button missing, back not working 使用导航组件时如何覆盖工具栏中后退按钮的行为 - How to override the behavior of back button in toolbar when using navigation component 处理导航后退按钮 - Handle Navigation Back Button 如果我使用导航组件在每个片段中设置工具栏,如何删除顶级片段工具栏中的后退按钮? - how to remove back button in the toolbar of top level fragment if I set toolbar in each fragment using navigation component? 使用导航组件和向上导航时如何返回上一个活动(工具栏上的后退按钮) - How to return to previous activity when using Navigation Component and Up navigation (back button on toolbar) 使用导航视图和工具栏不显示后退按钮 - Back button not displaying using navigation view and toolbar 如何使用导航组件隐藏图标并仅在工具栏中显示后退按钮? - How to hide the icons and only show the back button in the toolbar using navigation component? 按钮返回带有导航组件的 startDestination - button back in startDestination with navigation component Android - 在处理带片段的导航时更新活动中的工具栏标题 - Android - update toolbar title in activity while handle back navigation with fragment
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM