滚动界面预加载的实现原理
需求描述:
- 在 UI 还没有滚动要列表的 最底部时,触发加载数据
- 用户在下拉列表的过程中预加载数据,用户感知不到数据加载过程,体验流畅
核心点:判断预加载的时机
- 列表的当前窗口, 在距离 顶部/底部 小于 阀值 的时候触发
- 正在预加载时,不再加载数据
- 数据全部加载之后,不再加载数据
向下滚动预加载实现:
- 首先要监听列表的滚动事件
- 要能获取到列表的当前位置,和总高度
- 设定阀值
- 当列表的监听事件触发的时候,总高度 - 当前高度 < 阀值,执行预加载
- 执行预加载事件时,做一个标记,标记是否可进行预加载,则 4 的判断,修正如下:总高度 - 当前高度 < 阀值 && 可以预加载
- 数据加载完成之后,失败时、重置预加载标志,成功时、若加载出来的数据数量 >= 预加载的数据数量,则重置预加载标志,否则不动
1、2、4点实现核心点1,5、6点实现核心点2、3
Qt代码:
void ChannelTopArticleListView::init() {
connect(&_innerListView, &ListView::scrolled, this,
&ChannelTopArticleListView::onScrolled);
}
/// 滚动时触发此函数
void ChannelTopArticleListView::onScrolled() {
/// 针对实现点5:正在加载时,不再加载数据
QMutexLocker locker(&_cloudLoadedMutex);
if (_cloudLoaded) {
return;
}
/// 计算当期视图位置、阀值,判断是否可以预加载
int32 totalHeight = _innerListView.listViewHeight();
int32 current = _innerListView.currentListViewBottomPos();
/// 阀值 3 页
int32 preloadHeight = _innerListView.height() * 3;
if (totalHeight - current < preloadHeight) {
preloadTopArticle();
_cloudLoaded = true;
}
}