How to Save Fragment States with BottomNavigationView in Android?
Last Updated :
11 Dec, 2022
In Android applications, Activities and Fragments are from the foundation of the UI layer. It is now standard practice to load the UI with multiple fragments. For example, Instagram, Twitter, and a slew of other well-known apps. Imagine browsing some tweets in the Twitter app’s HomeFragment, navigating to the search screen, and then returning to the Home Screen only to discover that the Home Screen has been reloaded and now displays the first tweet! This is not a good user experience because the user must scroll back to the previous tweet. In this article, we’ll look at a simple method for dealing with and avoiding the recreation of these fragments, as well as saving their states. We’ll use a BottomNavigation View because we’ll be using multiple fragments on a single activity.
Let’s Begin:
- Make a Project
- Begin by creating a new Android Studio project.
- Choose an empty activity and a name of your choice for the next step.
- Name of the package: Anything you want.
- Kotlin is the language.
- Finish
Your first step is now complete.
Before we add the Bottom Navigation view to our activity main.xml file, we must first create a menu resource for the icons and text that will be displayed on our bottom navigation view! The following is the Navigation.xml file from our menu resource folder:
XML
<? xml version = "1.0" encoding = "utf-8" ?>
< item
android:id = "@+id/navigation_geeksforgeeks"
android:icon = "@drawable/geeksforgeeks"
android:title = "@string/geeksforgeeks" />
< item
android:id = "@+id/navigation_afteracademy"
android:icon = "@drawable/courses"
android:title = "@string/after_academy" />
< item
android:id = "@+id/navigation_user"
android:icon = "@drawable/coursesName"
android:title = "@string/coursesName" />
</ menu >
|
Let’s now include the bottom Navigation view component in our layout file!
XML
<? xml version = "1.0" encoding = "utf-8" ?>
< androidx.constraintlayout.widget.ConstraintLayout
android:layout_width = "match_parent"
android:layout_height = "match_parent"
tools:context = ".ui.activity.GfgMain" >
< include
layout = "@layout/main_gfg"
android:id = "@+id/someContainer"
app:layout_constraintBottom_toTopOf = "@+id/bottomNavigationView"
app:layout_constraintTop_toTopOf = "parent"
app:layout_constraintStart_toStartOf = "parent"
app:layout_constraintEnd_toEndOf = "parent" />
< com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
app:layout_constraintBottom_toBottomOf = "parent"
app:layout_constraintStart_toStartOf = "parent"
app:layout_constraintEnd_toEndOf = "parent"
android:background = "?android:attr/windowBackground"
app:menu = "@menu/navigation"
android:id = "@+id/bottomNavigationView" />
</ androidx.constraintlayout.widget.ConstraintLayout >
|
The layout we’ve included here is the one we’ll use to hold the fragment. So, let’s get started on it.
What is the purpose of this app?
We will simply create a simple app with three fragments: GeeksforGeeksFragment, AfterAcademyFragment, and UserFragment. The GeeksforGeeksFragment, AfterAcademyFragment and UserFragment each have one like button and one text field for displaying the number of likes. The main goal of this app is to prevent fragments from being recreated when the user switches between them.
So, how to do it?
Let’s make instances for our fragments as well as a global instance (let’s call it activeFragment) that stores the currently viewed fragment.
Kotlin
private val geeksforGeeksFragment = GeeksforGeeksFragment()
private val afterAcademyFragment = AfterAcademyFragment()
private val userFragment = UserFragment()
private val fragmentManager = supportFragmentManager
private var activeFragment: Fragment = GeeksforGeeksFragment
|
Let’s now add our fragments to the fragment manager:
Kotlin
supportFragmentManager.beginTransaction().apply {
add(R.id.someContainer, geeksforgeeksFragment, getString(R.string.gfg))
add(R.id.someContainer, afterAcademyFragment, getString(R.string.afterAcademy)).hide(afterAcademyFragment)
add(R.id.someContainer, userFragment, getString(R.string.user)).hide(userFragment)
}.commit()
|
Let’s take care of onNavigationItemSelected on our BottomNavigationView component now:
Kotlin
NavBar.setOnNavigationItemSelectedListener { menuItem ->
when (menuItem.itemId) {
R.id.navigation_geeksforgeeks-> {
fragmentManager.beginTransaction().hide(activeFragment).show(geeksForGeeksFragment).commit()
activeFragment = geeksForGeeksFragment
true
}
R.id.navigation_afteracademy-> {
fragmentManager.beginTransaction().hide(activeFragment).show(afterAcademyFragment).commit()
activeFragment = afterAcademyFragment
true
}
R.id.navigation_user -> {
fragmentManager.beginTransaction().hide(activeFragment).show(userFragment).commit()
activeFragment = userFragment
true
}
else -> false
}
}
|
GeekTip: Remember that we have stored our current fragment in our activeFragment field, which should be visible to the user.
Now all we have to do is to hide and show what we have created in a well-designed manner, so as to prevent any mishaps!
show() and hide()
Instead of adding and replacing fragments (creating fragment instances), we use the helper functions show() and hide(), which do not destroy or recreate our fragments but instead hide and show them. Because the fragment instances are not destroyed, the user can see the previous state of the fragment!
Conclusion
You can use a recycler view to replace a fragment UI by loading a list of 50+ items, scrolling to a random position, switching between fragments, and returning. This logic can be applied to a UI that includes a Scroll View. We hope this article has been of some assistance to you.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...