On screen rotation, I would like to have the var cardcount saved, so the user is not reset to to the first flash card when they rotate the screen.
I have attempted using the onSaveInstanceState and savedInstanceState.getInt() to keep the keep the value on the rotation, but it does not save the value.
I have seen alternatives to these functions, and I am not sure if I am going down some deep rabbit holes for something simple, or if I am swimming in the wrong ocean entirely.
Should I be looking into ViewModels and persistent storage, taking over manually with configuration changes, or shared preferences? The data is one variable, in one fragment.
class Components : Fragment() {
//Variables to keep track of which card, as well as which side is showing
private var cardcount = 0
private var cardfront = true
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//This is the function to set the image and text for the front and back of the flashard
fun select_card() {
card_front.setImageResource(map.getValue(cardcount).image)
card_back.text = map.getValue(cardcount).text
}
}
You definitely don't need to use ViewModel
s if you're not already, and SharedPreferences
might be too much just for this - but it depends on exactly what you want.
If you just want to keep a value while the app is "open" (including in the background) then the onSaveInstanceState()
method is made for that. Pop a value in the Bundle
it provides, and when your fragment needs to restore state it will be passed back in through onCreateView
, onViewCreated
, onViewStateRestored
... just pick it up in whichever lifecycle callback is most convenient, check the Bundle
isn't null (see next part!) and grab the value with the same key you used to store it.
If the fragment isn't restoring a previous state though, you won't get a bundle passed in. Your app can get closed by the system at any time (say to free up memory), so when it gets restarted, it's meant to look like it was running the whole time - that's why onSaveInstanceState
gets called, and why you get a bundle passed in, it's so you can put everything back the way it was when it went into the background.
But if the user closes the app, say by swiping it away, the next time you open it will be a fresh start - there's no state to persist, so you won't get the bundle. So if you do want to persist state between app runs (say the user's choice of language), you'll need to use something like SharedPreferences
to store some data, and load that in your Fragment.
ViewModel
s don't survive process death (the system killing your app in the background), so they don't persist state like onSavedInstanceState
does. They're more for things like configuration changes, where the app is going to stay in the foreground. You still have to be able to handle your state getting lost, and being able to recreate it. There are some other libraries to extend ViewModel
s to help you handle this but... just use a Bundle
for an Int
in my opinion, keep it simple
Definitely don't override configuration changes! That's a last resort and your example is like, the basic saved instance Bundle
use case