1

我目前正在开发一个 Android 应用程序,遇到了有关 BottomNavigationView 和 Fragments 的问题。我知道,有类似我的问题,但要么他们没有解决我的问题,要么他们没有有效的答案。

我的应用由五个顶级目的地片段组成。为了在它们之间导航,我使用了 BottomNavigationView。此外,我有几个片段用作较低级别的目的地,将从顶级片段之一调用。我使用 SafeArgs 插件导航到这些片段并将数据传递给。

我的 BottomNavigationView 配置如下所示:

val navView: BottomNavigationView = findViewById(R.id.nav_view)
val navController = (supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment).navController

val appBarConfiguration = AppBarConfiguration(setOf(
    R.id.navigation_dest1, R.id.navigation_dest2, R.id.navigation_dest3,
    R.id.navigation_dest4, R.id.navigation_dest5))
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController);

这种用法的问题在于,BottomNavigationView 似乎没有提供对在某处保存和存储片段以及重用这些实例进行导航的支持。它只是创建一个新实例并显示它。

目前每个片段都包含一些数据获取代码,例如在协程中运行网络请求或从文件系统加载文件。而且由于 BottomNavigationView 不保留片段实例,因此这些数据获取部分运行得太频繁了。
当然,我考虑过将数据获取过程放入主活动中,但这会导致应用程序启动速度整体变慢,并且不能解决每次用户在片段之间导航时仍需要重新创建片段的问题。

到目前为止,我已经找到了一半的解决方案。通过使用 SupportFragmentManager,手动添加、显示和隐藏我的片段可以正常工作。但是该应用程序运行速度明显变慢,并且使用 SafeArgs 导航到我的较低级别目的地不再起作用。我使用 SafeArgs 是因为它易于使用且非常轻松,而且我想继续使用它。

我尝试使用 SupportFragmentManager 手动管理这一切,但最终导致混乱和更差的性能。

有什么方法可以解决我的问题吗?一种方式,BottomNavigationView 可以与 SafeArgs 和 SupportFragmentManager 交互以重用片段,而不是在每个导航操作上重新创建它们?

(如果您需要更多信息或我的部分代码,请询问。我认为在这里发布我的完整代码没有多大意义。)

4

1 回答 1

1

您是否考虑过与片段共享 ViewModel 的选项?例如:

创建一个 ViewModel 类,如下所示:

 class MyViewModel: ViewModel() {
    ....
    ....
    }

然后,因为您的片段共享相同的 Activity,您可以声明以下内容(在 Kotlin 中):

 class MyFragment1: Fragment() {
        val viewModel: MyViewModel by activityViewModels()
        ....
        ....  
    }

    class MyFragment2: Fragment() {
        val viewModel: MyViewModel by activityViewModels()
        ....
        ....  

    }

在这种情况下,Fragment1 和 Fragment2 将共享同一个 ViewModel 实例,并且 ViewModel 将保留在内存中,直到 Activity 被销毁。导航出去时不会保留片段,但您可以保留每个片段的所有数据并重新使用它们。它快速而流畅,您不会介意是否重新创建片段,因为它的所有数据都将保存在内存中并准备好在共享 ViewModel 中使用。

另见官方文档: ViewModel 概述

于 2021-03-04T17:05:37.837 回答