当前位置: 移动技术网 > IT编程>移动开发>Android > item高度不同时Recyclerview获取滑动距离的方法

item高度不同时Recyclerview获取滑动距离的方法

2019年08月01日  | 移动技术网IT编程  | 我要评论

爱上一朵花的芬芳,克拉玛依二手房出售,九阴真经红粉白株

前言

最近遇到需求,要计算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));

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网