我正在尝试练习android体系结构组件分页
带有Room,MVVM和LiveData的本地+远程数据源
当我第一次滚动列表(获取远程数据)时,它会通过PagedList.BoundaryCallback中的 onItemAtEndLoaded 进入循环,但下次打开 Activity 时它会平滑滚动(获取本地数据)
这是我的github链接here!
谁能看看并帮助我解决问题,谢谢!
Activity
class PagingActivity : AppCompatActivity() {
lateinit var viewModel: PagingViewModel
lateinit var adapter: PagingAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_paging)
val factory = PagingViewModelFactory(PagingRepository(), application)
viewModel = ViewModelProviders.of(this,factory).get(PagingViewModel::class.java)
adapter = PagingAdapter()
recyclerView.adapter = adapter
viewModel.pagedListLiveData.observe(this, Observer {
adapter.submitList(it)
})
}
}
View 模型
class PagingViewModel(repository: PagingRepository, application: Application) :
AndroidViewModel(application) {
val pagedListLiveData = repository.getDataItem(application)
}
资料库
class PagingRepository : PagingRepositoryCallback {
private lateinit var localDataSource: DataSource.Factory<Int, DataItem>
override fun getDataItem(application: Application): LiveData<PagedList<DataItem>> {
val pagedListLiveData: LiveData<PagedList<DataItem>> by lazy {
localDataSource = DataItemDbHelper(application).getRoomDataItemDao().getAllDataItem()
val config = PagedList.Config.Builder()
.setPageSize(25)
.setEnablePlaceholders(false)
.build()
LivePagedListBuilder(localDataSource, config)
.setBoundaryCallback(PagingBoundaryCallback(application))
.build()
}
return pagedListLiveData
}
}
interface PagingRepositoryCallback {
fun getDataItem(application: Application): LiveData<PagedList<DataItem>>
}
边界回调
class PagingBoundaryCallback(context: Context) :
PagedList.BoundaryCallback<DataItem>() {
private var page = 2
private val api = AllPlayerApi.api
private val dao = DataItemDbHelper(context).getRoomDataItemDao()
override fun onZeroItemsLoaded() {
super.onZeroItemsLoaded()
api.getAllPlayer().enqueue(createWebserviceCallback())
}
override fun onItemAtEndLoaded(itemAtEnd: DataItem) {
super.onItemAtEndLoaded(itemAtEnd)
api.getAllPlayer(page).clone().enqueue(createWebserviceCallback())
}
private fun createWebserviceCallback(): Callback<AllPlayerData> {
return object : Callback<AllPlayerData> {
override fun onFailure(call: Call<AllPlayerData>?, t: Throwable?) {
Log.d("Huang", " get player fail ")
}
override fun onResponse(call: Call<AllPlayerData>?, response: Response<AllPlayerData>) {
Log.d("Huang", " onResponse " + page)
response.body()!!.data!!.forEach {
it.imageUrl = "https://pdc.princeton.edu/sites/pdc/files/events/new-nba-logo-1.png"
}
insertItemsIntoDb(response)
page++
}
}
}
private fun insertItemsIntoDb(response: Response<AllPlayerData>) {
GlobalScope.launch {
response.body()!!.data!!.forEach {
dao.insert(it)
}
}
}
}
最佳答案
逻辑,如果onItemAtEndLoaded
获得相同的itemAtEnd
,则什么也不做。
var lastItemAtEnd:DataItem? = null
override fun onItemAtEndLoaded(itemAtEnd: DataItem) {
lastItemAtEnd?.timestamp?.apply{
if(itemAtEnd.timestamp==this){
return;
}
}
super.onItemAtEndLoaded(itemAtEnd)
api.getAllPlayer(page).clone().enqueue(createWebserviceCallback())
}