listview 与 recyclerview获取准确滑动距离


前言

最近笔者遇到了关于获取listview与recyclerview滑动高度的需求,recyclerview提供了相应的方法,listview没有提供直接可以使用的方法,百度搜到的也只是获取一个大概距离,后来recyclerview由于item的高度改变,遇到了相似的问题,最后用相似的方法解决,记录一下

一、Listview

首先看listview提供了什么方法,他的scrolllistener有一个方法:

// firstVisibleItem 为首个可见的item的位置
//visibleItemCount 为屏幕里可见的item的数目
public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {

这里再解释一下firstVisibleItem, 我们知道listview是有复用回收的,被回收的就会从listview中移出,所以firstVisibleItem为第一个可见项的下标。可以总结为:
此时listview的第一个childview的下标就是firstVisibleItem

      即:   listView.getChildAt(0)获取到的view在你的adapter的数据中顺序为第firstVisibleItem。

那么该怎么判断滑动值呢,我们可以通过这个获取到的view与下标值firstVisibleItem进行操作。view可以直接获取其weight,同时我们知道view.getTop为其在其顶部父view的位置。
那么该怎么判断listview滑动值呢,我们按照下标值区分
当firstVisibleItem为0时,说明当前界面展示的第一个就是所有item的第一个,那么滑动值就是其top,所以有 滑动值 = view.getTop 同时我们可以将我们第一个view的高度存起来
当firstVisibleItem为6时(这里拿6做例子),说明当前界面展示的第一个就是所有item的第七个,此时滑动值应该为前面6个item的高度和+第七个item的getTop值。那么前6个item的高度怎么得到呢?刚刚说了可以通过view.getHeight获取其高度并且存起来,就在这里了。
代码:

         var heights = MutableList(10) {
            return@MutableList 0;
        }
        listView.setOnScrollListener(object : OnScrollListener {
            override fun onScrollStateChanged(view: AbsListView?, scrollState: Int) {
            }

            override fun onScroll(
                view: AbsListView,
                firstVisibleItem: Int,
                visibleItemCount: Int,
                totalItemCount: Int
            ) {
                val view = view.getChildAt(0);
                if (view == null) {
                    //有可能没有数据,所以返回
                    return
                }
                var scrollHeight = 0;
                if (firstVisibleItem == 0) {
                    heights[firstVisibleItem] = view.height;
                    scrollHeight = view.top;
                } else {
                    heights[firstVisibleItem] = heights[firstVisibleItem - 1] + view.height;
                    //由于是向上滑动,那么top是负数
                    scrollHeight = heights[firstVisibleItem - 1] + view.top*-1;
                }
                Log.e("滑动距离", scrollHeight.toString());

            }

        })

二、recyclerView

recyclerView本身提供了方法:

//dy即为本次滑动相对于上次滑动的偏移值
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){}

我们可以设置一个变量对dy进行累加,就可以得到滑动值。
但是既然提到Recyclerview,就肯定还有更进一步的,也是本次写这个文章的原因之一。本次作者的需求是: 外部有一个背景值,随着滑动距离变化,但是在滑动时,前面的view有可能改变高度(此时dy并不会刷新),这样就会出现还没滑动到最顶部,背景值就变成滑动到最顶端才会出现的颜色。
那我们就可以采取和listview相似的方式,实时获取到显示的第一个的高度,然后这样进行刷新。ListView告诉我们当前显示的第一个view的position,那Recyclerview怎么做呢:

//获取到此时在屏幕上的第一个view
        val view = recyclerView.getChildAt(0);
        //poiton即为该view在所有view中的位置
        val position =recyclerView.getChildAdapterPosition(view)

其他的流程就和listview一样了

总结

写博客怎么这么久呀,呜呜呜

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值