item高度不同时Recyclerview获取滑动距离的方法
程序员文章站
2022-06-04 12:11:48
前言
最近遇到需求,要计算recyclerview滑动距离,用提供的computeverticalscrolloffset()方法得到的值不是很准确。是基于item的...
前言
最近遇到需求,要计算recyclerview滑动距离,用提供的computeverticalscrolloffset()方法得到的值不是很准确。是基于item的平均高度算得,如果列表中item高度一致可以用此方法。问题来了,我的应用场景是各item高度不一,这时就只能另找方法了。
方法一:
网上找的方法,用一个变量去统计,每次滑动的时候累加y轴偏移量。item插入\移动\删除的时候,需要手动去更新totaldy,不然就会一直错下去。
private int totaldy = 0; mrecycler.addonscrolllistener(new recyclerview.onscrolllistener() { @override public void onscrolled(recyclerview recyclerview, int dx, int dy) { totaldy -= dy; } }
方法二:
方法一比较麻烦,而且坑较多。所以考虑重写linearlayoutmanager的computeverticalscrolloffset()方法,既然原生方法是按平均高度计算的,那重写该计算逻辑,就能达到我们想要的效果。
1.统计列表已展示过的item的高度,在每次布局完成的时候,用一个map记录positon位置item对应的view的高度。
private map<integer, integer> heightmap = new hashmap<>(); int count = getchildcount(); for (int i = 0; i < count; i++) { view view = getchildat(i); heightmap.put(i, view.getheight()); }
2.重写computeverticalscrolloffset(),找到当前屏幕第一个可见item的position,通过heightmap循环累加0到positon的item高度,再加上第一个可见item不可见部分高度。最终得到整个列表的滑动偏移。
@override public int computeverticalscrolloffset(recyclerview.state state) { if (getchildcount() == 0) { return 0; } int firstvisiableposition = findfirstvisibleitemposition(); view firstvisiableview = findviewbyposition(firstvisiableposition); int offsety = -(int) (firstvisiableview.gety()); for (int i = 0; i < firstvisiableposition; i++) { offsety += heightmap.get(i) == null ? 0 : heightmap.get(i); } return offsety; }
3.最终代码
public class offsetlinearlayoutmanager extends linearlayoutmanager { public offsetlinearlayoutmanager(context context) { super(context); } private map<integer, integer> heightmap = new hashmap<>(); @override public void onlayoutcompleted(recyclerview.state state) { super.onlayoutcompleted(state); int count = getchildcount(); for (int i = 0; i < count ; i++) { view view = getchildat(i); heightmap.put(i, view.getheight()); } } @override public int computeverticalscrolloffset(recyclerview.state state) { if (getchildcount() == 0) { return 0; } try { int firstvisiableposition = findfirstvisibleitemposition(); view firstvisiableview = findviewbyposition(firstvisiableposition); int offsety = -(int) (firstvisiableview.gety()); for (int i = 0; i < firstvisiableposition; i++) { offsety += heightmap.get(i) == null ? 0 : heightmap.get(i); } return offsety; } catch (exception e) { return 0; } } }
mrecycler.setlayoutmanager(new offsetlinearlayoutmanager(mcontext));
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Android列表动图展示的实现策略
下一篇: Android实现超级棒的沉浸式体验教程