配置更改不保存应用程序状态 MVVM
Posted
技术标签:
【中文标题】配置更改不保存应用程序状态 MVVM【英文标题】:Configuration Changes Not Save App State MVVM 【发布时间】:2022-01-21 18:27:50 【问题描述】:我正在构建一个电影应用程序。有一个与父尺寸匹配的回收器视图,以及 1 个搜索操作按钮(SearchView)。
当我搜索电影时,一切正常,但是当我改变方向时,活动就失去了它的状态。 recyclerview 变空了,我需要重新搜索电影。
我正在使用 MVVM,但我知道它不会发生..
谢谢!
这是存储库:
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
这是 ViewModel:
class MainViewModel : ViewModel()
fun getMovieBySearch(searchAfter : String) : LiveData<List<Movie>>
return mainRepository.searchAfter(searchAfter)
这是 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
【问题讨论】:
【参考方案1】:您需要在视图模型中保存所需的状态。例如,
var persistedMovies = arrayListOf<Movie>()
当搜索返回有效响应时,
mainViewModel.persistedMovies = newList
现在列表作用域到视图模型,并且通过方向变化保持不变。
【讨论】:
嘿,我不明白如何将它保存在 viewModel 中,我确实喜欢这样:pastebin.com/W6GA58tw 但是现在当我搜索它时,它只是不停地加载。 当然,将第一行放入视图模型,将第二行放入链接的第 38 行。现在mainViewModel.persistedMovies
在活动的onCreate()
中可用。
嘿,是的,我可以访问它,但它不是实时数据或可变实时数据,所以我该如何使用它?
您想用它填充 UI,对吧?如何使用它真的取决于您……请注意,不需要新的搜索,它可以解决原始问题。
感谢您的回答,最后一个问题。因此,当我在搜索电影后旋转设备时,recyclerview 变为空,因为它再次调用 onCreate 但我还没有搜索任何内容,并且在 onCreate 中没有任何东西可以膨胀 recyclerview。但是,如果我有流行电影或任何我在 onCreate 中膨胀的开始列表怎么办?当我搜索一部电影然后旋转屏幕时,它会用流行电影列表而不是我搜索的内容来膨胀回收器视图。我该如何克服呢?谢谢!以上是关于配置更改不保存应用程序状态 MVVM的主要内容,如果未能解决你的问题,请参考以下文章
Android - MVVM 中 ViewModel 状态的最佳实践?