RecyclerView GridView模式同一行,使其高度平齐,自动适应高度最大item

简介: RecyclerView GridView模式同一行,使其高度平齐,自动适应高度最大item
先看一下效果图

1688294853474.png

前言

在开发中,产品会给你绞尽脑汁设计出类似上述UI,细心的小伙伴发现其中的奥秘没有,实际上是相同行,高等相等,自适应最多字数文本内容,每行有每行的最大高度,高度不同!也许大家刚看此样式,so easy~,但要实际去开发,会发现这种样式倒是不是很好处理,于是我在网上找了找,但是案例基本也不尽人意,一般都是计算item高度,不是很好操作,下面给大家讲解一下俩种实现方案,大家接着往下看。



实现思路

下面给大家介绍俩种实现思路,第一种为网上常规思路计算高度,第二种是转换思维方式实现方案

注:大家说可能会想到高度给match_parent,wrap_content,这些均实现不了,每个item给固定高度,这样也不行,此问题衍生到了item高度问题

1、第一种思路

首先回顾一下我们要实现的内容,gradView列表,同一行高度相同,自适应文本最大内容,只限于同一行,说到这里,我们会想到计算同一行每个item高度,选其中最高的那一个maxHeigh,然后将同一行每个item高度都设置成maxHeigh,每行计算每行的,下面给大家分解一下实现方案

首先需要页面绘制完毕,此时才可以获取到所有子view的高度,需要在onLayout执行

第一步获取子view有多少个,获取grieView一行有多少个numColumns,将每一行子view放到一起来计算出最高的高度,方法如下

private void setHeights() {
        ListAdapter adapter = getAdapter();
        if(adapter != null) {
            for(int i = 0; i < getChildCount(); i+=numColumns) {
                // Determine the maximum height for this row
                int maxHeight = 0;
                for(int j = i; j < i+numColumns; j++) {
                    View view = getChildAt(j);
                    if(view != null && view.getHeight() > maxHeight) {
                        maxHeight = view.getHeight();
                    }
                }
            }
        }
    }
再次讲解一下,numColumns为一行有几个,i+=numColumns为一次增加一行的数量,然后再遍历每一行子view,获取最大高度maxHeight高度,

第一步完毕,此时输出的是每一行最大高度maxHeight高度,下一步我们要用这个高度来设置每一行每个item的高度

private void setHeights() {
        ListAdapter adapter = getAdapter();
        if(adapter != null) {
            for(int i = 0; i < getChildCount(); i+=numColumns) {
                // Determine the maximum height for this row
                int maxHeight = 0;
                for(int j = i; j < i+numColumns; j++) {
                    View view = getChildAt(j);
                    if(view != null && view.getHeight() > maxHeight) {
                        maxHeight = view.getHeight();
                    }
                }
                //Log.d(TAG, "Max height for row #" + i/numColumns + ": " + maxHeight);
                // Set max height for each element in this row
                if(maxHeight > 0) {
                    for(int j = i; j < i+numColumns; j++) {
                        View view = getChildAt(j);
                        if(view != null && view.getHeight() != maxHeight) {
                            view.setMinimumHeight(maxHeight);
                        }
                    }
                }
            }
        }
    }
再次讲解一下,和第一步遍历每一行view方式相同,获取到每个子view将高度赋值给每个子view

依次类推,核心计算规则就是上述展示这样,这样虽然能实现,但是存在问题,项目demo中也有这种样式展示案例,

参考链接,但实际实现了此效果,但不理想,存在问题,有兴趣的小伙伴可以研究一下,下面给大家介绍第二种实现思路



2、第二种思路

我们再来回顾一下我们要实现的内容,gradView列表,同一行高度相同,自适应文本最大内容,只限于同一行,第一种思路已经讲解了如何用高度来计算来实现高度等齐效果,下边我要带大家换一种思维方式来实现,不去计算高度,完全和计算高度不沾边的一种思路,思路明确其实很简单,我们去想,一行中我们要取最大textView的高度,第一种思路是计算出这个高度给其他view,那我们也可以将内容复制给其他TextView,这样也实现了高度统一了,但是有人会说,这样岂不是一行内容都一样了,那我们可以这样,放俩个TextView,一个正常显示,一个占位隐藏,so ~恍然大悟了没有,也就是每一行的view都展示一个文本最长的内容,用占位隐藏来显示,同一行高度每个item都有最大高度的TextView,那每行高度就实现了等齐了,明白了这种思路是不是感觉很简单,但是涉及到一个计算规则问题,下面给大家讲解一下如何来拆分每行最大文本内容

一个adapter本身有一个List集合,我们再拷贝出来一个,每一行放文本最大字数的List,列表展示的时候依次赋值即可

public void changeSpanCount(int spanCount) {
        String str = "";
        mListCopy.clear();
        for (int i = 0; i < mList.size(); i++) {
            if (mList.get(i).getBytes().length > str.getBytes().length) {
                str = mList.get(i);
            }
            if (i % spanCount >= spanCount - 1 || i == mList.size() - 1) {
                for (int z = 0; z < spanCount; z++) {
                    mListCopy.add(str);
                }
                str = "";
            }
        }
思路拆分一下:遍历真是集合中的文本内容,比对出字节最大的那个,赋值给str,i % spanCount >= spanCount - 1,集合的下标与每行的行数取余,如果等于每行的行数-1,那代表一行中最后一个,比如如果是 一行有3个,遍历从0开始,那便是0,1,2
2%3=3-1为每行最后一个,依次类推,往mListCopy集合中添加与行数相同数量 的  最大文本字数str,依次类推
i == mList.size() - 1的含义为集合末尾不够整行的文本,这时候就需要处理不够一行的情况,
i集合下标,从0开始,如果与集合数量-1相等,就是到了最后末尾的那一个

思路拆分一下:遍历真实集合中的文本内容,比对出字节最大的那个,赋值给str,i % spanCount >= spanCount - 1,
集合的下标与每行的行数取余,如果等于每行的行数-1,那代表一行中最后一个,比如如果是 一行有3个,遍历从0开始,那便是0,1,2
2%3=3-1为每行最后一个,依次类推,往mListCopy集合中添加与行数相同数量 的  最大文本字数str,依次类推
i == mList.size() - 1的含义为集合末尾不够整行的文本,这时候就需要处理不够一行的情况,
i集合下标,从0开始,如果与集合数量-1相等,就是到了最后末尾的那一个

根据上述思路,将原集合List和ListCopy集合数量相等,赋值给列表,List正常展示,ListCopy占位隐藏展示,便实现了上述效果

以上思路demo中都有实现案例,可移步到demo中详细查看

最后,祝大家创作愉快

相关文章
|
监控 Android开发 C语言
深度解读Android崩溃日志案例分析2:tombstone日志
深度解读Android崩溃日志案例分析2:tombstone日志
1866 0
|
Android开发 开发者 存储
Android可折叠收缩伸展的Expandable分组RecyclerView:模型抽象和封装(二)
Android可折叠收缩伸展的Expandable分组RecyclerView:模型抽象和封装(二) 如今Android这种可收缩伸展的Expandable RecyclerView是如此常用,在附录1的基础上,我重新把模型进行了抽象和封装,设计了一套新的架构和简洁的使用方式支持这种功能。
4549 0
|
传感器 存储 Java
Android 3D效果的实现
本文详细讲解了如何在Android中实现3D效果,基于官方Demo并结合实际需求进行调整。通过传感器(Sensor)获取设备旋转数据,利用OpenGL ES绘制3D立方体,实现了动态旋转的视觉效果。文章分为需求分析、效果展示、实现步骤及源码解析,涵盖传感器注册与注销、OpenGL核心方法使用等内容,适合初学者学习参考。文末附完整代码,便于实践操作。
532 0
Android 3D效果的实现
|
消息中间件 设计模式 监控
并发设计模式实战系列(9):消息传递(Message Passing)
🌟 大家好,我是摘星!🌟今天为大家带来的是并发设计模式实战系列,第九章,废话不多说直接开始~
334 0
|
传感器 Android开发 开发者
Android自定义view之3D正方体
本文介绍了如何通过手势滑动操作实现3D正方体的旋转效果,基于Android自定义View中的GLSurfaceView。相较于使用传感器控制,本文改用事件分发机制(onTouchEvent)处理用户手势输入,调整3D正方体的角度。代码中详细展示了TouchSurfaceView的实现,包括触控逻辑、OpenGL ES绘制3D正方体的核心过程,以及生命周期管理。适合对Android 3D图形开发感兴趣的开发者学习参考。
358 0
|
网络安全 图形学 Android开发
Unity与安卓丨AS报错:SSL peer shut down incorrectly
Unity与安卓丨AS报错:SSL peer shut down incorrectly
Unity与安卓丨AS报错:SSL peer shut down incorrectly
|
机器学习/深度学习 人工智能 搜索推荐
AI在医疗诊断中的应用与未来发展趋势分析
【10月更文挑战第9天】 本文深入探讨了人工智能(AI)在医疗诊断领域的现状及其应用,包括影像识别、临床数据处理及个性化治疗方案的制定。通过具体案例分析,展示了AI技术如何提高诊断准确性、缩短诊断时间,并减轻医生的工作负担。同时,本文还讨论了AI在医疗诊断中面临的伦理问题和法律障碍,以及解决这些问题的可能途径。最后,对AI在未来医疗行业中的发展潜力进行了展望,指出其在提升医疗服务质量和效率方面的巨大潜力。
1373 2
|
开发框架 前端开发 JavaScript
电商商品数据库的设计和功能界面的处理
电商商品数据库的设计和功能界面的处理
|
XML 搜索推荐 Java
28. 【Android教程】自动补全文本框 AutoCompleteText
28. 【Android教程】自动补全文本框 AutoCompleteText
456 2
|
开发工具 git
Git回滚代码到某个commit
回退命令:$ git reset --hard HEAD^ 回退到上个版本$ git reset --hard HEAD~3 回退到前3次提交之前,以此类推,回退到n次提交之前 $ git reset --hard commit_id 退到/进到 指定commi...
12424 0

热门文章

最新文章