1

I'm currently writing an app that displays a list of movies. The app has 8 fragments that contain the recyclerview: Trending Movies, Action, Comedy, Horror, Romance, Scifi, Search, and Favorites.

The items in the recyclerview contain a checkbox that adds the movie to the favorites. When I scroll or exit the app, the checkbox state resets. I'm trying to save the state of the checkbox using savestate but it's not working.

Can anyone please tell me what I'm doing wrong? Below is the viewmodel.

Thank you.

MoviesListViewModel.kt

package com.example.moviesapp.ui

import androidx.lifecycle.*
import com.example.moviesapp.network.MoviesRepository
import com.example.moviesapp.network.MoviesResults
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

const val DEFAULT_QUERY = " "
const val ACTION_MOVIES = "moviesAction"
const val COMEDY_MOVIES = "moviesComedy"
const val HORROR_MOVIES = "moviesHorror"
const val ROMANCE_MOVIES = "moviesRomance"
const val SCIFI_MOVIES = "moviesScifi"
const val TRENDING_MOVIES = "moviesTrending"


enum class MovieApiStatus {LOADING, ERROR, DONE}


@HiltViewModel
class MoviesListViewModel @Inject constructor(
    private val repository: MoviesRepository,
  private var state: SavedStateHandle

): ViewModel() {

       private val _moviesAction: MutableLiveData<List<MoviesResults.Movies>> = state.getLiveData(ACTION_MOVIES)
       val moviesAction: LiveData<List<MoviesResults.Movies>> = _moviesAction

       private val _moviesComedy: MutableLiveData<List<MoviesResults.Movies>> = state.getLiveData(COMEDY_MOVIES)
       val moviesComedy: LiveData<List<MoviesResults.Movies>> = _moviesComedy

       private val _moviesHorror: MutableLiveData<List<MoviesResults.Movies>> = state.getLiveData(HORROR_MOVIES)
       val moviesHorror: LiveData<List<MoviesResults.Movies>> = _moviesHorror

       private val _moviesRomance: MutableLiveData<List<MoviesResults.Movies>> = state.getLiveData(
           ROMANCE_MOVIES)
       val moviesRomance: LiveData<List<MoviesResults.Movies>> = _moviesRomance

       private val _moviesScifi: MutableLiveData<List<MoviesResults.Movies>> = state.getLiveData(SCIFI_MOVIES)
       val moviesScifi: LiveData<List<MoviesResults.Movies>> = _moviesScifi

    private val _moviesTrending: MutableLiveData<List<MoviesResults.Movies>> = state.getLiveData(TRENDING_MOVIES)
    val moviesTrending: LiveData<List<MoviesResults.Movies>> = _moviesTrending

    private val _networkState = MutableLiveData<MovieApiStatus>()
    val networkState: LiveData<MovieApiStatus> = _networkState





    init {
        getMovies()

    }




 fun getAction() {
     viewModelScope.launch {
         _moviesAction.value = repository.getActionMovies()
     }
 }

     fun getComedy() {
         viewModelScope.launch {
             _moviesComedy.value = repository.getComedyMovies()

         }

     }

    fun getHorror() {
        viewModelScope.launch {
            _moviesHorror.value = repository.getHorrorMovies()
        }

    }
    fun getRomance() {
        viewModelScope.launch {
            _moviesRomance.value = repository.getRomanceMovies()
        }

    }

    fun getScifi() {
        viewModelScope.launch {
            _moviesScifi.value = repository.getScifiMovies()

        }

    }

    fun getTrending() {
        viewModelScope.launch {
            _moviesTrending.value = repository.getTrendingMovies()
        }

    }









    private var currentQuery = MutableLiveData(DEFAULT_QUERY)







     val movies = currentQuery.switchMap {
            queryString ->
       liveData {
           emit(repository.getSearchResults(queryString))
       }
   }

    fun searchMovies(query: String) {

    currentQuery.value = query

    }

    private fun getMovies() {
        viewModelScope. launch {
            _networkState.value = MovieApiStatus.LOADING
            try {
                _networkState.value = MovieApiStatus.DONE
            }
            catch (e: Exception) {
                _networkState.value = MovieApiStatus.ERROR

            }

        }

    }



    class MoviesListViewModelFactory @Inject constructor(private val repository: MoviesRepository, private val state: SavedStateHandle): ViewModelProvider.Factory {
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            if (modelClass.isAssignableFrom(MoviesListViewModel::class.java)) {
                @Suppress("UNCHECKED_CAST")
                return MoviesListViewModel(repository, state) as T
            }
            throw IllegalArgumentException("Unknown ViewModel class")

        }


    }



}




3
  • You should store in SharedPreferences or equivalent like DataStore etc because saveState works only until the activity is stopped or destroyed Commented Aug 27, 2021 at 9:35
  • Saving in saveState wont persist the data when you exit the application . The data in save state only persist when the activty has rotated or application is in the background . Commented Aug 27, 2021 at 9:42
  • SharedPreferences is now depracated. What should I use then? Commented Aug 27, 2021 at 10:05

1 Answer 1

0

Interface for accessing and modifying preference data returned by Context.getSharedPreferences(String, int). For any particular set of preferences, there is a single instance of this class that all clients share. Modifications to the preferences must go through an Editor object to ensure the preference values remain in a consistent state and control when they are committed to storage. Objects that are returned from the various get methods must be treated as immutable by the application.

Note: This class provides strong consistency guarantees. It is using expensive operations which might slow down an app. Frequently changing properties or properties where loss can be tolerated should use other mechanisms. For more details read the comments on Editor.commit() and Editor.apply().

Note: This class does not support use across multiple processes.

in your case you can simply store the key-value pair to record the relevant selection.

Sign up to request clarification or add additional context in comments.

3 Comments

Shared preferences is depracated though
Jetpack DataStore is a good alternative
I tried to save the state of the checkbox using jetpack datastore, but I couldn't access the checkbox since the checkbox is inside a layout and that layout is used in the recyclerview.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.