3

I have the single activity with several fragments on top, as Google recommends. In one fragment I wish to place a switch, and I wish to still know it's state when I come back from other fragments. Example: I am in fragment one, then I turn on the switch, navigate to fragment two or three, go back to fragment one and I wish to load that fragment with that switch in the on position as I left it.

I have tried to copy the examples provided by google advocates, just to see the code to fail hard and do nothing.

/////////////////////////////////////////////////////////////////
//Inside the first fragment:
class myFragment : Fragment() {

    companion object {
        fun newInstance() = myFragment()
    }

    private lateinit var viewModel: myViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.my_fragment, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        **viewModel = ViewModelProvider(this, SavedStateVMFactory(this)).get(myViewModel::class.java)

        //Here I was hoping to read the state when I come back.
        switch_on_off.isChecked = viewModel.getSwRoundTimerInit()**

        subscribeToLiveData() //To read liveData

        switch_on_off.setOnCheckedChangeListener { _, isChecked ->
            viewModel.setOnOff(isChecked)
        }
}//End of onActivityCreated
//other code...

/////////////////////////////////////////////////////////////////////////
//On the fragment ViewModel

class myViewModel(private val **mState: SavedStateHandle**) : ViewModel() {

    //SavedStateHandle Keys to save and restore states in the App
    private val swStateKey = "SW_STATE_KEY"

    private var otherSwitch:Boolean //other internal states.

    //Init for the other internal states
    init {      
        otherSwitch = false
    }

    fun getSwRoundTimerInit():Boolean{
        val state = mState[swStateKey] ?: "false"
        return state.toBoolean()
    }

    fun setOnOff(swValue:Boolean){
        mState.set(swStateKey, swValue.toString())
    }

}

This does not work. It always loads the default (off) value, as if the savedState is null all the time.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62

1 Answers1

0

change

//fragment scope
viewModel = ViewModelProvider(thisSavedStateVMFactory(this)).get(myViewModel::class.java) 

to

//activity scope
viewModel = activity?.let { ViewModelProviders.of(it,SavedStateVMFactory(this)).get(myViewModel::class.java) }

https://developer.android.com/topic/libraries/architecture/viewmodel#sharing

tskulbru
  • 2,336
  • 1
  • 20
  • 38
charmy
  • 31
  • 2
  • 7