I got 3 fragments and 1 activity. MainActivity
, CameraFragment
, HomeFragment
, HistoryFragment
I just want to save all HistoryFragment
states so whenever user access it, it won't recreated again.
whatever, I have found the most common solution with fragmentManager
Here's all my codes,
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val historyFragment = HistoryFragment()
private val homeFragment = HomeFragment()
private val cameraFragment = CameraFragment()
private val fragmentManager = supportFragmentManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val ft = fragmentManager.beginTransaction()
ft.add(R.id.fragmentContainerView, historyFragment, Constants.TAG_HISTORY)
.hide(historyFragment)
.add(R.id.fragmentContainerView, homeFragment, Constants.TAG_HOME)
cameraViewModel.activeFragment = if (hasPermission()) {
//camera
ft.add(R.id.fragmentContainerView, cameraFragment, Constants.TAG_CAMERA)
ft.hide(homeFragment)
cameraFragment
} else {
//home
homeFragment
}
ft.commit()
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
val navController = navHostFragment.findNavController()
binding.bottomNav.setupWithNavController(navController)
binding.bottomNav.setOnItemSelectedListener { item ->
when (item.itemId) {
R.id.historyFragment -> {
when (cameraViewModel.activeFragment) {
is HomeFragment -> fragmentManager.beginTransaction().hide(cameraViewModel.activeFragment).show(historyFragment).commit()
}
cameraViewModel.activeFragment = historyFragment
item.isChecked = true
true
}
}
}
HistoryFragment.kt
class HistoryFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentHistoryBinding.inflate(inflater, container, false)
// tool bar
(activity as AppCompatActivity).setSupportActionBar(binding.toolBarHistory)
val appBarConfiguration = AppBarConfiguration(
setOf(R.id.historyFragment, R.id.homeFragment, R.id.cameraFragment)
)
NavigationUI.setupActionBarWithNavController(requireActivity() as AppCompatActivity, findNavController(), appBarConfiguration)
return binding.root
}
}
toolbar in fragment_history.xml
<androidx.appcompat.widget.Toolbar
android:id="@+id/tool_bar_history"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"/>
The problem is when I open app, MainActivity
runs then it shows homeFragment
and when I click on history item in bottom navigation, homeFragment
gets hide and it shows historyFragment
but with label Home in title bar not History
I have used Logcat and I have detected that when I call: navController.currentDestination?.id
in historyFragment, I get id for homeFragment
I hope you give me solution for this or any other way to save fragment with no bugs thanks in advance
Well this should be a comment but I can't. Still, I'm sharing it with you in case you still don't find a solution.
I don't have much context on what specifically you want to store from the fragment or why. I would still consider that if you want to store the entire state of a fragment [data or steps] while the activity is active, I would recommend using an activity-scoped view model
private val someViewModel: SomeViewModel by activityViewModels()
So that every change you want to store from the History fragment can be stored in the view model and then if you go to another fragment and then come back to the fragment, it gets this data and shows it to the user, so it is recreated but with the most recent data and not from scratch.
As additional data to find this delegate you should add the dependency:
implementation "androidx.fragment:fragment-ktx:1.6.1"