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

抓住人生中的一分一秒,胜过虚度中的一月一年!

小做个动图开篇引题


懒洋洋.gif
先看一下效果图
Demo样式图.gif

前言

在开发中,产品会给你绞尽脑汁设计出类似上述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中详细查看

最后,祝大家创作愉快

CSDN地址:https://download.csdn.net/download/loocanp/81938415

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容