mikasaloli
mikasaloli

Reputation: 53

How can i keep livedata running in viewmodel even fragment is destroyed?

Here i have 2 ui pages: Home Fragment and Timer Fragment

enter image description here

Timer fragment's job is display timer counter value that running in viewModel. but my problem is when i back to home fragment and go to timer fragment again the Timer get reset and start countdown from begin again. So is there a way to continue countdown even i pop back to Home Fragment Likes when timer has 30s left and i back to HomeFragment for 5s then enter TimerFragment again then it display 25s left not restart counting from the begin? Thank you so much

here my code TimerViewModel.kt

lateinit var timer : CountDownTimer 
var timerData =  MutableLiveData<Long>()

fun startTimer(){
    timer = object : CountDownTimer(30000,1000){
        override fun onTick(millisUntilFinished: Long) {
            timerData.value = millisUntilFinished/1000
        }

        override fun onFinish() {
            timerData.value = 1000
        }
    }
    if (timerData.value==null){
        timer.start()
    }
}

TimerFragment.kt

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    viewModel = injectViewModel(viewModelFactory)
    val binding = FragmentTimerBinding.inflate(inflater, container, false)
    viewModel.startTimer()
    viewModel.timerData.observe(viewLifecycleOwner, Observer { result ->
        binding.timeLeft = result.toString()
    })
    return binding.root
}

and here how i go from homeFragment to TimerFragment using Navigation

HomeFragmentDirections.actionHomeToTimerFragment()
it.findNavController().navigate(direction)

My viewModel injection function

inline fun <reified T : ViewModel> Fragment.injectViewModel(factory: 
ViewModelProvider.Factory): T {
return ViewModelProviders.of(this, factory)[T::class.java]
}

Upvotes: 1

Views: 1170

Answers (2)

Kazim Hussain
Kazim Hussain

Reputation: 41

Your ViewModelStoreOwner should be the parent activity of the Fragment for the ViewModel to persist between Fragment creation and destruction.

In your injectViewModel function do something like this:

return ViewModelProvider(requireActivity(), viewModelFactory).(TimerViewModel::class.java)

Using this appraoch your ViewModel will bind to the lifecycle of your Activity and will only be destroyed after your activity is destroyed.

Upvotes: 1

Love Mahajan
Love Mahajan

Reputation: 11

Initialize Viewmodel in fragment using getActivity() method Example: ViewModelProvider(requireActivity())[ViemodelName::class.java]

In this way the viewmodel instance will be bind to the activity lifecycle and it will be cleared only when activity is destroyed and your timer instance will not get destroyed even if your fragment is destroyed.Let me know if you have any confusion.

Upvotes: 1

Related Questions