最近在研究安卓的Kotlin,碰到的问题是:首页是一个多列表页面,见下图

Screenshot_1587867878.png
顶部接口分类接口大于三个,每个分类的列表含有大于三个模块(例如:动作片,喜剧片,科幻片...),这样算起来了启动加载的数据接口,大概有六个,甚至更多.... 这种情况一次性请求 显然不太科学,一是接口返回需要时间,增加启动时间,二是其中一个接口请求失败,无法及时刷新数据.所以就想到当前item出现在屏幕中的时候在加载进行刷新.这样请求接口就减少了很多.如果用户不滑到底部,那么底部的item数据就不用加载了.也减少了不必要的数据请求.
代码如下:
view!!.home_fr_list.addOnScrollListener(object: RecyclerView.OnScrollListener(){
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
Log.e("scrole","调用了ScrollStateChanged")
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val lastPosition = linerlayout.findLastVisibleItemPosition()
//:找到最后一个显示的
val currentTypeM = homeList[lastPosition]
//如果当前数组为空 并且不再 加载中 那就去请求数据
if (!currentTypeM.videList.isNotEmpty() && !currentTypeM.isLoading){
currentTypeM.isLoading = true
Log.e("滚动:RecyclerView","${currentTypeM.modeModel.resource_type_name}")
paramsM = ParamsModel(mod_id = CurrentCatorM.mod_id,resource_type_id = currentTypeM.modeModel.resource_type_id)
getPersenter()!!.getCurrentCatorgryVideoListModel(paramsM,lastPosition)
}
}
})
在监听事件里面 判断当前item 数据源是否有数据,如果为空就带上当前Position和参数去请求数据,以便数据请求回来能够找到刷新位置.然后在数据赋值哪里:
override fun <T> setData(data: T, identi: String,currentPostion:Int) {
//:分块数据
if (identi == "banner") {
bannerList = data as MutableList<BannerModel>
val refreshData = homeList[0]
refreshData.bannerList = bannerList
//:赋值 显示数据
homeAdpter.notifyItemChanged(0)
}
//:接受数据
if (identi == "list"){
val listModel = data as HomeListModel
val refreshData = homeList[currentPostion]
refreshData.videList = listModel.data
homeAdpter.notifyItemChanged(currentPostion)
}
}
使用notifyItemChanged 来刷新当前请求位置的数据.这样就完成了首页数据懒加载的操作.
目前数据能够正常加载啦~~~
遗留问题:
就是第一屏数据item 大于两个 ,那么第一个和和第二个都不会取请求数据,这个通过 把findLastVisibleItemPosition 换成findFirstVisibleItemPosition 可以解决 总是加载屏幕中的加载第一个item.这样也会有个问题就是,滑到底部的话,如果存在大于两个item,最后一个item数据不会被夹在.
问题正在解决中.........
如果你有很好的建议欢迎指正!随时在线!!!!!
补充数据加载方式
val firstPosition = linerlayout.findLastVisibleItemPosition()
val lastPosition = linerlayout.lastLastVisibleItemPosition()
visibleItemsArr = firstPosition - lastPosition ;得到可见屏幕内可见items下标数组
然后 for循环遍历请求屏幕内的可见模块的数据.