现在 Android 开发中列表 Header 吸顶效果比较常见了,针对 ListView、RecyclerView 都有多种实现方式。之前开发也碰到过,都是用的三方库或者框架。今天主要写下直接利用 Android 原生来进行实现。
页面大致如下:
针对本文的场景,相当于一个 HEADER 对应一组 Image。所以,最好是有个 Map 结构,然后每个 Image item 都能清楚的知道自己所属哪个 HEADER。
1 | class MatchedImageAdapter(val map: LinkedHashMap<HEADER, List<Image>>) |
然后按照这个结构,利用泛型,来实现列表多 Type 效果。
1 | private val dataList = ArrayList<Any>() |
另外,针对图片 Item 的网格布局,直接使用 GridLayoutManager 的 spanSize 就能达到效果。
1 | val layoutManager = GridLayoutManager(context, MAX_COUNT) |
看到 Header 有个“选择”按钮是可以点击的,所以就有了本文。不用支持点击的话,可以直接使用 ItemDecoration 来达到吸顶效果了。
如果要支持点击效果,我采取的方案是:在 RecyclerView 上面盖一层 Header,然后用过滑动监听来设置 Header 的偏移,从而达到吸顶效果。
那么核心便是滑动的监听了:
1 | matchedImageRv.addOnScrollListener(object : RecyclerView.OnScrollListener() { |
看下 shouldTranslationY 的代码:
1 | /** |
position 是当前位置,如果当前位置是 HEADER,那么下一行数据肯定不是 HEADER,直接返回 false。如果当前位置是图片 item,那么往下数 3 个,一定能得到下一行数据的类型。中途有可能被 HEADER 类型截断,从而直接返回。然后结合高度,top 值,来判断是否需要设置 translationY,从而达到吸顶效果。
然后看下覆盖 HEADER 的点击事件设置:
1 | autoMatchHeader.selectAllTv.setOnClickListener { |
通过滑动获取当前位置的数据 currentHeader,然后改变这个 currentHeader 对应数据中的具体分组的数据。
写的有点乱,但是要点都写出了,over~