我有一个简单的概念验证应用程序,它只包含2个片段:MainFragment
和RepositoryFragment
以及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()
}