Home > Net >  Configuration Changes Not Save App State MVVM
Configuration Changes Not Save App State MVVM

Time:12-21

I am building a movie app. There is a recyclerview matching parent size,and 1 search action button(SearchView).

When I search for a movie,everything is working fine,but when I change orientation,the activity just lose it's state. the recyclerview turns empty and I need to search for the movie again.

I am using MVVM and I know its not suppose to happen..

Thank you!

This is the Repository:

class MainRepository {

   
    private val searchAfterMutableLiveData = MutableLiveData<List<Movie>>()
    private val apiService : GetFromApi = APIService.retrofitClientRequest
    private val apiKey = "censored"

    fun searchAfter(searchAfter : String) : MutableLiveData<List<Movie>>{

        apiService.searchAfter(apiKey,searchAfter)?.enqueue(object : Callback<MovieListResult?> {
            override fun onResponse(
                call: Call<MovieListResult?>,
                response: Response<MovieListResult?>
            ) {

                if (response.isSuccessful){
                    searchAfterMutableLiveData.value = response.body()?.moviesResults
                    Log.e("SearchMovieListResults","Result: ${searchAfterMutableLiveData.value}")
                }

            }

            override fun onFailure(call: Call<MovieListResult?>, t: Throwable) {
                Log.e("SearchMovieListResults","Failed: ${t.message}")
            }
        })

        return searchAfterMutableLiveData
    }


}

This is the ViewModel:

class MainViewModel : ViewModel(){

    fun getMovieBySearch(searchAfter : String) : LiveData<List<Movie>>{
        return mainRepository.searchAfter(searchAfter)
    }

}

This is the MainActivity:

class MainActivity : AppCompatActivity() {

    private val mainViewModel : MainViewModel by viewModels()
    private lateinit var mainRecyclerView : RecyclerView
    private lateinit var mainAdapter : MainRecyclerViewAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initRecyclerView()

    }


    private fun initRecyclerView() {

        mainRecyclerView = findViewById(R.id.mainRecyclerView)
        mainRecyclerView.setHasFixedSize(true)
        mainRecyclerView.layoutManager = GridLayoutManager(this,1)

    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.main_menu,menu)

        val searchView = menu.findItem(R.id.menu_search_movie).actionView as androidx.appcompat.widget.SearchView

        searchView.queryHint = "Search By Name,Actor .."
        searchView.setOnQueryTextListener(object : androidx.appcompat.widget.SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(whileTextChange: String?): Boolean {

                //Clear SearchView
                searchView.isIconified = true
                searchView.setQuery("", false)
                searchView.onActionViewCollapsed()
                mainViewModel.getMovieBySearch(whileTextChange.toString()).observe(this@MainActivity,object : Observer<List<Movie>?> {
                    override fun onChanged(newList: List<Movie>?) {
                        if (newList != null) {

                            mainAdapter = MainRecyclerViewAdapter(newList)
                            mainRecyclerView.adapter = mainAdapter
                            //mainAdapter.changeCurrentList(newList)

                        }
                    }
                })

                return false
            }

            override fun onQueryTextChange(whileTextChange: String?): Boolean {
                Log.e("onQueryTextChange","Text: $whileTextChange")
                return false
            }
        })



        return true
    }


}

CodePudding user response:

You need to save the desired state in the viewmodel. For example,

var persistedMovies = arrayListOf<Movie>()

and when the search returns a valid response,

mainViewModel.persistedMovies = newList

Now the list is scoped to the viewmodel and persists through orientation changes.

  • Related