Android跨应用重装场景带偏移量恢复RecyclerView滚动位置问题
问题根因
你使用的两个偏移值统计逻辑完全不匹配:
recyclerView.computeVerticalScrollOffset()返回的是列表从最顶部开始累计的总滚动距离,是全局偏移值scrollToPositionWithOffset(position, offset)方法的第二个参数要求的是指定position对应的item顶部,距离RecyclerView父容器顶部的像素偏移,二者维度完全不同,直接传入必然会出现错位。
正确实现方案
1. 存储阶段保存正确的参数
不要使用全局滚动偏移,改为存储两个维度的参数:
// 取第一个可见item的position,允许半显示用findFirstVisibleItemPosition,要求完全显示用findFirstCompletelyVisibleItemPosition val firstVisiblePos = recyclerViewLayoutManager.findFirstVisibleItemPosition() // 取这个可见item的顶部距离RecyclerView顶部的偏移 val firstVisibleItemView = recyclerViewLayoutManager.findViewByPosition(firstVisiblePos) val itemTopOffset = firstVisibleItemView?.top ?: 0
将firstVisiblePos和itemTopOffset存入Firebase即可。
如果你的业务需求必须基于最后一个可见item做定位,逻辑对等:存储最后一个可见item的position,以及该item底部距离RecyclerView底部的偏移即可
2. 恢复阶段正确执行滚动
必须等RecyclerView的列表数据加载完成、item布局渲染完成后再调用恢复方法,避免因为item未测量导致偏移失效:
// 用post方法确保在RecyclerView布局完成后执行滚动逻辑 recyclerView.post { recyclerViewLayoutManager?.scrollToPositionWithOffset(firstVisiblePos, itemTopOffset) }
适配特殊场景说明
如果你的列表item高度是动态计算的、或者重装后首次加载的列表数据和上次退出时存在增删变更,可以额外存储上次第一个可见item对应的业务唯一ID,恢复时先通过ID匹配到当前列表对应的position,再应用偏移,即可适配数据变化的场景,进一步提升恢复准确率。
内容的提问来源于stack exchange,提问作者Sagar Patel
相关产品推荐
相关产品推荐

