【发布时间】:2019-07-05 11:40:06
【问题描述】:
recycleView 不会在初始加载时从网络更新结果。
回收视图:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mRecyclerAdapter = MovieListAdapter(context)
rvMovieList.apply {
// Dedicated layouts for Screen Orientation
if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
layoutManager = LinearLayoutManager(context)
} else {
layoutManager = GridLayoutManager(context, 2)
}
adapter = mRecyclerAdapter
}
}
并使用 ViewModel 中的 LiveData 监听网络结果。
LiveData监听sn-p下面的Fragment:
override fun onResume() {
super.onResume()
// Listen to data change
viewModel.getMovies().observe(this, mMovieListObserver)
}
private val mMovieListObserver: Observer<PagedList<MovieItem>> = Observer { movieItems ->
Log.d(TAG, "MovieItems: ${movieItems.size}")
showEmptyList(movieItems?.size == 0)
mRecyclerAdapter.submitList(movieItems)
}
private fun showEmptyList(isEmpty: Boolean) {
tvEmptyListView.visibility = if (isEmpty) View.VISIBLE else View.GONE
rvMovieList.visibility = if (isEmpty) View.GONE else View.VISIBLE
}
override fun onPause() {
viewModel.getMovies().removeObserver(mMovieListObserver)
super.onPause()
}
具有讽刺意味的是,结果会在后续加载时填充 recycleView。我觉得 LiveData 没有按预期工作。引入emptyView时的期望是根据网络结果显示/隐藏recycleView/EmptyView。
ViewModel 粘贴在下面:
class MovieListViewModel : ViewModel() {
private val PAGE_SIZE = 10
internal var movies: LiveData<PagedList<MovieItem>>
init {
val dataSourceFactory = MovieDataSourceFactory()
val pagedListConfig = PagedList.Config.Builder()
.setInitialLoadSizeHint(PAGE_SIZE)
.setPageSize(PAGE_SIZE)
.setEnablePlaceholders(true)
.build()
movies = LivePagedListBuilder(dataSourceFactory, pagedListConfig)
// .setBoundaryCallback() TODO
.build()
}
fun getMovies(): LiveData<PagedList<MovieItem>> {
return movies
}
}
感谢您抽出宝贵时间,感谢您对解决方案或最佳做法的任何意见。谢谢。
回购:https://gitlab.com/faisalm/MovieDirect
////---
更新了 DataSourceFactory 和 DataSource。
class MovieDataSourceFactory : DataSource.Factory<Int, MovieItem>() {
private val mutableLiveData = MutableLiveData<MovieDataSource>()
override fun create(): DataSource<Int, MovieItem> {
val dataSource = MovieDataSource()
mutableLiveData.postValue(dataSource)
return dataSource
}
}
class MovieDataSource internal constructor() : PageKeyedDataSource<Int, MovieItem>() {
private val movieDbService: MovieDbService = RetrofitFactory.create()
override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, MovieItem>) {
val moviesListCall = movieDbService.fetchLatestMoviesPaged(Constants.API_KEY, 1)
moviesListCall.enqueue(object : Callback<MoviesList> {
override fun onResponse(call: Call<MoviesList>, response: Response<MoviesList>) {
if (response.isSuccessful) {
val moviesLists = response.body()?.results
callback.onResult(moviesLists!!, 1, 2)
}
}
override fun onFailure(call: Call<MoviesList>, t: Throwable) {}
})
}
override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, MovieItem>) {}
override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, MovieItem>) {
val moviesListCall = movieDbService.fetchLatestMoviesPaged(Constants.API_KEY, params.key)
moviesListCall.enqueue(object : Callback<MoviesList> {
override fun onResponse(call: Call<MoviesList>, response: Response<MoviesList>) {
if (response.isSuccessful) {
val moviesLists = response.body()?.results
callback.onResult(moviesLists!!, params.key + 1)
}
}
override fun onFailure(call: Call<MoviesList>, t: Throwable) {}
})
}
}
【问题讨论】:
-
“结果在后续加载时填充recycleView”是什么意思?
-
您是否通知适配器
mRecyclerAdapter.submitList(movieItems)数据更改? (类似notifyDataSetChanged或更好的东西)? -
@JeelVankhede 不需要那个,因为他正在使用 PagedList
-
您是否遇到任何错误,如果您发布您的 DataSource 类可能会很好?
-
@RahulShukla 虽然结果没有反映在初始加载中,但一旦用户回家/离开应用程序并回来,就会填充列表。
标签: android kotlin android-recyclerview viewmodel android-livedata