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

小做个动图开篇引题

iOS tableHeaderView自适应高度 recyclerview高度自适应_赋值

先看一下效果图

iOS tableHeaderView自适应高度 recyclerview高度自适应_GridView_02

前言

在开发中,产品会给你绞尽脑汁设计出类似上述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占位隐藏展示,便实现了上述效果