当前位置: 首页 > news >正文

实现一个能设置MaxLine的LayoutManager

实现一个能设置MaxLine的LayoutManager

有时候,我们会遇到这种需求:一个线性的列表布局,当item量很少的时候,就是wrap_content直接展示完所有item,但是当item数量超过某个数时就要固定高度,让其变成可滑动展示更多的item。所以我们第一个想法就是用RecyclerView,应该没人会用ListView或自己写个自定义ViewGroup吧。

但是当我们使用RecyclerView+maxHeight的时候,会发现其实maxHeight是不起作用的。

<span><span><span>&lt;</span>androidx.recyclerview.widget.RecyclerView</span><span><span>android:</span>id</span><span><span>=</span><span>"</span>@+id/recyclerView<span>"</span></span><span><span>android:</span>layout_width</span><span><span>=</span><span>"</span>match_parent<span>"</span></span><span><span>android:</span>layout_height</span><span><span>=</span><span>"</span>wrap_content<span>"</span></span><span><span>android:</span>maxHeight</span><span><span>=</span><span>"</span>100dp<span>"</span></span> <span>/&gt;</span></span>

warp_recycler_view.gif

那么为什么会造成这种原因呢?其实在我之前写的一篇博客也提到过:RecyclerViewonMeasure的转交给了LayoutManager,并且LayoutManager里面有个isAutoMeasureEnabled()方法用来配置LayoutManager是否开启自测量。我们常用的LinearLayoutManagerGridLayoutManager都是默认返回true的。

博客地址

实现思路

所以实现思路就很简单了:设定一个maxLine参数,当RecyclerViewitemCount小于这个值isAutoMeasureEnabled()都是返回true,让LayoutManager自测量。当itemCount大于maxLine时就重写onMeasure方法,在里面去设置RecyclerView限定宽高

代码实现

class MaxLineLinearLayoutManager : LinearLayoutManager {private var mMaxLine = 0constructor(context: Context?,maxLine: Int) : super(context) {Helper.checkMaxCount(maxLine)this.mMaxLine = maxLine}constructor(context: Context?,orientation: Int,reverseLayout: Boolean,maxLine: Int) : super(context, orientation, reverseLayout) {Helper.checkMaxCount(maxLine)this.mMaxLine = maxLine}override fun onMeasure(recycler: RecyclerView.Recycler,state: RecyclerView.State,widthSpec: Int,heightSpec: Int) {if (itemCount &lt;= mMaxLine || itemCount == 0) {super.onMeasure(recycler, state, widthSpec, heightSpec)return}val child = recycler.getViewForPosition(0)//addView(child)measureChildWithMargins(child, 0, 0)val itemWidth = getDecoratedMeasuredWidth(child)val itemHeight = getDecoratedMeasuredHeight(child)removeAndRecycleView(child, recycler)val widthMode = View.MeasureSpec.getMode(widthSpec)val heightMode = View.MeasureSpec.getMode(heightSpec)var width = 0var height = 0if (orientation == HORIZONTAL) {height = if (heightMode == View.MeasureSpec.EXACTLY) {View.MeasureSpec.getSize(heightSpec)} else {itemHeight}width = itemWidth * mMaxLine} else {width = if (widthMode == View.MeasureSpec.EXACTLY) {View.MeasureSpec.getSize(widthSpec)} else {itemWidth}height = itemHeight * mMaxLine}setMeasuredDimension(width, height)}override fun isAutoMeasureEnabled(): Boolean {if (itemCount &lt;= mMaxLine) {return super.isAutoMeasureEnabled()}return false}}

代码很简单,应该不加注释也能看懂。如果看不懂的可以去看看我之前的那篇分析自定义LayoutManager的文章。

博客地址

recyclerView.layoutManager = MaxLineLinearLayoutManager(this, maxLine = 3)

maxline_layoutmanager.gif

源码地址

https://github.com/simplepeng/MaxLineLayoutManager


http://www.mrgr.cn/news/16584.html

相关文章:

  • 【C++ 第十八章】C++11 新增语法(1)
  • 《软件工程导论》(第6版)第4章 形式化说明技术 复习笔记
  • VSCode+debugpy远程调试
  • 强推第一本给程序员看的AI Agent教程终于来啦!全方位解析LLM-Agent
  • 空岛战争的正确姿势
  • 【鸿蒙开发从0到1-day03】
  • 震惊!更换GPU会改变LLM的行为
  • 《高等代数》“爪”字型行列式
  • 性能分析之使用 Jvisualvm dump 分析示例
  • LabVIEW开发高温摩擦试验机
  • 自然语言处理系列四十八》Word2vec词向量模型》算法原理
  • Unclutter - 苹果电脑(Mac)桌面文件笔记剪贴板管理工具
  • 奉加微PHY6233开门狗;超时时间对不上;好像应用不需要喂狗只需要开启定时器就行;底层是通过空闲任务喂狗的
  • bbr 和 inflight 守恒的收敛原理
  • AR 眼镜之-系统通知定制(通知中心)-实现方案
  • DORIS - DORIS简介
  • ​T​P​一​面​
  • Kubernetes 网关流量管理:Ingress 与 Gateway API
  • 免费申请https的方法有哪些
  • 【网络安全】服务基础第一阶段——第七节:Windows系统管理基础---- Web与FTP服务器