如何在 Android 中使用 BottomNavigationView 保存片段状态?
在 Android 应用程序中,Activity 和 Fragments 来自 UI 层的基础。现在使用多个片段加载 UI 是标准做法。例如,Instagram、Twitter 和许多其他知名应用程序。想象一下在 Twitter 应用程序的 HomeFragment 中浏览一些推文,导航到搜索屏幕,然后返回主屏幕却发现主屏幕已重新加载,现在显示第一条推文!这不是一个好的用户体验,因为用户必须滚动回上一条推文。在本文中,我们将介绍一种处理和避免重新创建这些片段以及保存它们的状态的简单方法。我们将使用底部导航视图,因为我们将在单个活动上使用多个片段。
让我们开始:
- 做一个项目
- 首先创建一个新的 Android Studio 项目。
- 为下一步选择一个空活动和您选择的名称。
- 包裹名称:任何你想要的。
- Kotlin 是一种语言。
- 结束
您的第一个项目现已完成。
在我们将底部导航视图添加到我们的活动 main.xml 文件之前,我们必须首先为将在底部导航视图上显示的图标和文本创建一个菜单资源!以下是我们菜单资源文件夹中的 Navigation.xml 文件:
XML
XML
Kotlin
private val GeeksforGeeksFragment = GeeksforGeeksFragment()
private val afterAcademyFragment = AfterAcademyFragment()
private val gfgFragment = GfgFragment()
private val fragmentManager = supportFragmentManager
private var activeFragment: Fragment = GeeksforGeeksFragment
Kotlin
gfgFragment.beginTransaction().apply {
add(R.id.someConatainer, courseAct, getString(R.string.user)).hide(userFragment)
add(R.id.someConatainer, coursePrices, getString(R.string.coursePriceActivity)).hide(coursePriceActivity)
add(R.id.someConatainer, geeksforgeeksFragment, getString(R.string.gfg))
}.commit()
Kotlin
NavBar.setOnNavigationItemSelectedListener { menuItem ->
when (menuItem.itemId) {
R.id.navigation_geeks-> {
fragmentManager.beginTransaction().hide(activeFragment).show(geeksForGeeksFragment).commit()
activeFragment = geeksForGeeksFragment
true
}
R.id.navigation_coursesPrice-> {
fragmentManager.beginTransaction().hide(activeFragment).show(afterAcademyFragment).commit()
activeFragment = afterAcademyFragment
true
}
R.id.navigation_user -> {
fragmentManager.beginTransaction().hide(activeFragment).show(courseNameFragment).commit()
activeFragment = courseNameFragment
true
}
else -> false
}
}
现在让我们在布局文件中包含底部导航视图组件!
XML
我们在这里包含的布局是我们将用来保存片段的布局。所以,让我们开始吧。
这个应用程序的目的是什么?
我们将简单地创建一个包含三个片段的简单应用程序:MindOrksFragment、AfterAcademyFragment 和 UserFragment。 GeeksforGeeksFragment 和 CourseActiviy 各有两个点赞按钮和两个用于显示点赞数的文本字段。访问次数通过单击按钮和 UserFragment 中的文本显示。这个应用程序的主要目标是防止当用户在片段之间切换时重新创建片段。
那么,该怎么做呢?
让我们为我们的片段创建实例以及存储当前查看的片段的全局实例(我们称之为 activeFragment)。
科特林
private val GeeksforGeeksFragment = GeeksforGeeksFragment()
private val afterAcademyFragment = AfterAcademyFragment()
private val gfgFragment = GfgFragment()
private val fragmentManager = supportFragmentManager
private var activeFragment: Fragment = GeeksforGeeksFragment
现在让我们将片段添加到片段管理器中:
科特林
gfgFragment.beginTransaction().apply {
add(R.id.someConatainer, courseAct, getString(R.string.user)).hide(userFragment)
add(R.id.someConatainer, coursePrices, getString(R.string.coursePriceActivity)).hide(coursePriceActivity)
add(R.id.someConatainer, geeksforgeeksFragment, getString(R.string.gfg))
}.commit()
现在让我们处理 BottomNavigationView 组件上的 onNavigationItemSelected:
科特林
NavBar.setOnNavigationItemSelectedListener { menuItem ->
when (menuItem.itemId) {
R.id.navigation_geeks-> {
fragmentManager.beginTransaction().hide(activeFragment).show(geeksForGeeksFragment).commit()
activeFragment = geeksForGeeksFragment
true
}
R.id.navigation_coursesPrice-> {
fragmentManager.beginTransaction().hide(activeFragment).show(afterAcademyFragment).commit()
activeFragment = afterAcademyFragment
true
}
R.id.navigation_user -> {
fragmentManager.beginTransaction().hide(activeFragment).show(courseNameFragment).commit()
activeFragment = courseNameFragment
true
}
else -> false
}
}
GeekTip: Remember that we have stored our current fragment in our activeFragment field, which should be visible to the user.
现在我们要做的就是隐藏和展示我们以精心设计的方式创造的东西,以免发生任何意外!
显示()和隐藏()
我们不是添加和替换片段(创建片段实例),而是使用辅助函数 show() 和 hide(),它们不会破坏或重新创建我们的片段,而是隐藏和显示它们。因为片段实例没有被销毁,所以用户可以看到片段之前的状态!
结论
您可以使用回收器视图来替换片段 UI,方法是加载 50 多个项目的列表、滚动到随机位置、在片段之间切换并返回。此逻辑可应用于包含 Scroll View 的 UI。我们希望这篇文章对您有所帮助。