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



我有一个简单的概念验证应用程序,它只包含2个片段:MainFragmentRepositoryFragment以及1个活动:MainActivity

这是我的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>

主要活动:

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()
}

主要活动布局:

<?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>

这是从MainFragment导航到RepositoryFragment的部分

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

存储库片段:

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)
}

理想情况下,我想实现以下导航:

MainFragment导航到RepositoryFragment,然后单击Toolbar或设备上的后退按钮,应导航回MainFragment

然而,在我的情况下,只有工具栏上的后退按钮才能正常工作。设备上的后退按钮将直接退出应用程序。

我想知道我在代码中遗漏了什么?

更新

这个问题背后的一个真正问题是,我将livedata用于单个事件(处理点击事件以导航到RepositoryFragment(。

看了这篇文章之后:https://proandroiddev.com/livedata-with-single-events-2395dea972a8

GabrieleMariotti提供了解决方案,并解决了问题。

我要感谢@GabrieleMariotti,他以极大的耐心帮助了我。

删除action:中的app:popUpTo="@id/id_main"app:popUpToInclusive="true

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

onCreate方法中使用:

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

并且在您的onSupportNavigateUp方法中:

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

最新更新