我正在尝试练习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())
}

10-07 19:49