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.