我用GridView来显示一些字符串,而字符串的长度是不固定的,然后就遇到问题了:有时字符重叠,有时显示不全,有时两种问题同时出现。见下图:


图一 GridView显示重叠、显示不全

这到底是什么情况,该怎么解决呢?
第一反应是上网查找方案,有两种方案:
1, 自定义GridView,重写onMeasure,如下:

   public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int expandSpec = MeasureSpec.makeMeasureSpec(     Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);     super.onMeasure(widthMeasureSpec, expandSpec);     }  

经过测试,不能解决问题。

2, 先在Adapter中获取GridView的高度,然后均分给每排:
代码如下:

        int height = mGv.getHeight();  int width = mGv.getWidth();         //得到GridView每一项的高度与宽度
if(height>0){GridView.LayoutParams params = new GridView.LayoutParams(width / 3,  height /2);
//针对我的情况,3列2排,直接写数测试//设置每一行的高度和宽度view.setLayoutParams(params);}

发现有时能解决问题,有时不行。当然对于图一中遇到的问题,也是不能解决的,但是情况有所变化,截图如下:


图二 GridView显示不全,不可滑动

可以看出,没有重叠了,但是第一排的字,已经有丢失的情况发生了。第二排的也是丢失了,因为此时的GridView是不能滑动的。(图一的情况,还可以滑动显示全第二排的内容)

我的目标是两排都能显示全,而且不用滑动来进行显示。那么,该怎么办呢?既然没有现成的解决方案,那就自己来研究下GridView的工作逻辑吧。

下面描述下我的测试环境,也就是问题现场:
主界面使用了一个GridView,里面的子项内容是一个TextView,文本的内容是一项水果名,共有6种,分为2排3列显示。

xml文件中,GridView的布局:

    <GridView android:id="@+id/grid_view"android:layout_width="match_parent"android:layout_height="wrap_content"android:numColumns="3" >
</GridView>

GridView子项的内容布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><TextView
        android:id="@+id/fruit_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textSize="45sp"android:layout_marginLeft="5dip"/></LinearLayout>

提供的数据如下:

    private void initFruits() {Log.i("MainActivity", "log: initFruits");Fruit banana = new Fruit("仙人蕉");fruitList.add(banana);Fruit apple = new Fruit("红嘎拉苹果");fruitList.add(apple);Fruit strawberry = new Fruit("玉麟草莓");fruitList.add(strawberry);Fruit pineapple = new Fruit("北界红提葡萄");fruitList.add(pineapple);Fruit orange = new Fruit("褚橙");fruitList.add(orange);  Fruit watermelon = new Fruit("黑美人西瓜");fruitList.add(watermelon);} 

适配器里面是这样写的:

public View getView(int position, View convertView, ViewGroup parent) {Fruit fruit = getItem(position);View view;ViewHolder viewHolder;TextView tv_record ;String strLog;if(convertView == null){        view = LayoutInflater.from(getContext()).inflate(resoureId, null);strLog = "log: new ViewHolder ";viewHolder = new ViewHolder();viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name);view.setTag(viewHolder);            viewHolder.fruitName.setText(fruit.getName());          }else{strLog = "log: use old ViewHolder ";view = convertView;viewHolder = (ViewHolder)view.getTag();             }tv_record = viewHolder.fruitName;Log.i("FruitAdapter", strLog+" pos="+position+" fruitName=" + fruit.getName()+" mGv.getHeight="+mGv.getHeight());Log.i("FruitAdapter", "log: getView: lines="+tv_record.getLineCount() +" LineHeight="+ tv_record.getLineHeight()+" tv.height="+tv_record.getHeight());return view;}

我测试的主要方法,就是看getView()中的输出信息。如下:

07-24 22:11:58.010: I/FruitAdapter(8061): log: new ViewHolder  pos=0 fruitName=仙人蕉 mGv.getHeight=0
07-24 22:11:58.010: I/FruitAdapter(8061): log: getView: lines=0 LineHeight=105 tv.height=0
07-24 22:11:58.030: I/FruitAdapter(8061): log: use old ViewHolder  pos=0 fruitName=仙人蕉 mGv.getHeight=0
07-24 22:11:58.030: I/FruitAdapter(8061): log: getView: lines=2 LineHeight=105 tv.height=0
07-24 22:11:58.060: I/FruitAdapter(8061): log: use old ViewHolder  pos=0 fruitName=仙人蕉 mGv.getHeight=458
07-24 22:11:58.060: I/FruitAdapter(8061): log: getView: lines=2 LineHeight=105 tv.height=0

我们可以看出,在getView()中,第一个位置的view会执行3次,

第一次,新建view,所有高度值都是0 ,除了字体的高度是105。
第二次,convertView已经存在了,我们看到lines=2,即此时已经根据文本内容计算出行数了,但是GridView的总高度仍然是0。
第三次,GridView的总高度已经有值了,但是TextView的高度仍然是0。

怎样才能看到TextView的高度呢?
我有一次在调整文本初始化的顺序时,画面显示不全,在滑动显示时,看见了TextView的高度值不为0 ,此时界面如下:

图三 GridView显示不全,可滑动显示

Log如下:

07-25 21:54:05.760: I/FruitAdapter(28214): log: use old ViewHolder  pos=0 fruitName=褚橙 mGv.getHeight=248
07-25 21:54:05.760: I/FruitAdapter(28214): log: getView: lines=1 LineHeight=105 tv.height=124
07-25 21:54:05.760: I/FruitAdapter(28214): log: use old ViewHolder  pos=1 fruitName=玉麟草莓 mGv.getHeight=248
07-25 21:54:05.760: I/FruitAdapter(28214): log: getView: lines=2 LineHeight=105 tv.height=229

有了这些数据,就能做一些分析工作了:
例如内容为“褚橙”时,字符串没有换行,字高105,TextView高度为124,则字与控件中还有空余为124-105=19。
对于“玉麟草莓”,字分2行,字高105,两行为105*2=210,加上空余间隔为19,加起来是210+19=229,与日志中的值相符合。
此时GridView的高度为248,恰好是124的2倍。应该是通过内容的总个数计算出来的(后面的试验用更丰富的数据支撑了这个判断)。
在构建 FruitAdapter 时,已经通过输入参数 fruitList,知道总共有多少项了,本例中为6项。又已经在布局中设置了numColumns=”3” ,就知道格子有几排了:6/3=2。这样,按照第一个格子的高度值124,总计2排,计算出GridView的总体高度为2*124=248。

通过滑动屏幕,能看到文本总共有6行。说明下,此时文本的顺序是:褚橙,玉麟草莓,北界红提葡萄,红嘎拉苹果,仙人蕉,黑美人西瓜。我通过调整字体,使两个字为一行,超过则换行。此时的6行的高度,应该是两个3行相加的结果。第一排,毫无疑问,只有“北界红提葡萄”是分为3行的,所以,第一行的内容高度,是取的最后一个格子的高度。第二排是不是也是使用的最后一个格子的高度呢?通过调整第二排的内容顺序,以及进一步的调整到2列3排,我验证了这个想法。

总结:
1, GridView有一个视图高度,其计算方法是:第一个格子的高度*总的排数;
2, GridView有一个内容高度,其计算方法是:每排最后一个格子的高度之和;
3, 若视图高度小于内容高度,则内容显示不全,可以滑动来显示;
4,GridView每排的高度,不是固定的,使用的是最后一个格子的高度。
5,若某一排中有内容超过最后一个格子高度的,则多出的部分,会显示到下一排上,从而出现重叠现象。若这排就是最后一排了,则多出的部分不能显示。

根据以上结论,我们可以分析前面3张图中遇到的问题:
第一张图:字符重叠的原因,第二个格子的高度(3行)大于该排中最后一个格子的高度(2行)。字符显示不全的原因:GridView总高度=2行*2=4行,而内容高度为2行+3行=5行,内容高度大于视图高度,从而显示不全。

第二张图:字符显示不全的原因:GridView视图高度=2行*2=4行,进行均分,则每排为2行,所有高度值超过2行的格子,超过2行的内容部分都显示不了。

第三张图:字符显示不全的原因:GridView总高度=1行*2=2行,而内容高度为3行+3行=6行,内容高度大于视图高度,从而显示不全。

再回到最初的问题,若要把内容显示全,需要满足两个条件:
1,第一个格子的高度,是所有格子高度的最大值;
2,每排的最后一个格子的高度,是这一排中所有格子高度的最大值;

对于每个格子高度都一样的,这两个条件完全满足。
但是字符串的长度不确定,从而导致了格子的高度不确定,怎么办呢?

我的办法是,先全部遍历一遍所有格子,找出内容最多的,放在第一个格子里,通过系统的3次尝试,获取出高度最大值来。对于字符串而言,自然是最长的字符串换行最多,从而有最大的高度值。然后将所有格子的高度统一设置为这个值。当然,计算完成后,将第一个格子的内容也恢复为正常内容。

关键代码如下:

package com.example.gridviewdemo;import java.util.List;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.TextView;public class FruitAdapter extends ArrayAdapter<Fruit> {private int  resoureId;GridView mGv;static int heightTextView=0;static int numFlushTextView=0;public FruitAdapter (Context context, GridView gv, int textViewResourceId,List<Fruit> objects) {super(context, textViewResourceId,objects);resoureId=textViewResourceId;this.mGv = gv;Log.i("FruitAdapter", "log: consturctor: resoureId=" + resoureId);}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {Fruit fruit = getItem(position);View view;ViewHolder viewHolder;TextView tv_record ;String strLog;if(convertView == null){        view = LayoutInflater.from(getContext()).inflate(resoureId, null);strLog = "log: new ViewHolder ";viewHolder = new ViewHolder();viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name);view.setTag(viewHolder);            viewHolder.fruitName.setText(fruit.getName());          tv_record = viewHolder.fruitName;Log.i("FruitAdapter", strLog+" pos="+position+" fruitName=" + fruit.getName()+" mGv.getHeight="+mGv.getHeight());Log.i("FruitAdapter", "log: getView: lines="+tv_record.getLineCount() +" LineHeight="+ tv_record.getLineHeight()+" tv.height="+tv_record.getHeight());if(heightTextView>0){Log.i("adapter","to SetHeight="+heightTextView);tv_record.setHeight(heightTextView);        }//只在第一次的时候,获取最长字符串,并进行设置。以便于在后面进入时,获取到系统测算的实际布局高度值if((position==0)&&(numFlushTextView==0)){int posForMaxLen=0;int maxLength=0;for(int i=0;i<getCount();i++){                      int len=getItem(i).getName().length();if(maxLength < len ){                           maxLength = len ;                   posForMaxLen=i;}Log.i("FruitAdapter","log: i="+i+" len="+len+" maxLength="+maxLength);}                   tv_record.setText(getItem(posForMaxLen).getName().toString());  numFlushTextView++; }   }else{strLog = "log: use old ViewHolder ";view = convertView;viewHolder = (ViewHolder)view.getTag();         tv_record = viewHolder.fruitName;Log.i("FruitAdapter", strLog+" pos="+position+" fruitName=" + fruit.getName()+" mGv.getHeight="+mGv.getHeight());Log.i("FruitAdapter", "log: getView: lines="+tv_record.getLineCount() +" LineHeight="+ tv_record.getLineHeight()+" tv.height="+tv_record.getHeight());//获取系统测算的实际布局高度值int height = mGv.getHeight();  if(height>0){int numRows=mGv.getCount()/mGv.getNumColumns();heightTextView = height/numRows;if(position==0){tv_record.setText(getItem(0).getName().toString());//将内容改回原本应该使用的内容tv_record.setHeight(heightTextView);numFlushTextView++;                                     Log.i("FruitAdapter","log: heightView="+heightTextView+" numFlush="+numFlushTextView);}                   }                       }return view;}class ViewHolder{TextView fruitName;}}

最终效果如下:

后记:
现在其实还有个问题,就是若某一排中所有格子的内容都比较少,例如只有2行的高度,而GridView按最大高度值计算,给它安排的是3行的高度,就会有一行的空白了。
所以对于第一排之外的其他排,应该计算该排中内容最多的那个格子的高度值,用来设置该排最后一个格子的高度。
但是,Android系统只对第一排的第一个格子进行了3次计算,其他排的格子没有这种计算,所以用这种方法就实现不了。
若有高人有方法实现这种精准的排列,请留言告诉我,万分感谢!

源码下载:
http://download.csdn.net/detail/lintax/9590371

解决GridView内容显示不全问题相关推荐

  1. 关于div的滚动条滚动到底部,内容显示不全的问题。(已解决)

    关于div的滚动条滚动到底部,内容显示不全的问题.(已解决) 参考文章: (1)关于div的滚动条滚动到底部,内容显示不全的问题.(已解决) (2)https://www.cnblogs.com/th ...

  2. 计算机word文档无法预览,电脑打开Word文档内容显示不全或显示空白怎么解决

    很多用户会在电脑中使用必装的Microsoft Office系列软件.有用户在电脑中打开Word文档,发现内容显示不全,有时候显示空白,那么应该怎么解决这一问题?对此,大家可以参考本教程提供的方法. ...

  3. 用于解决listview嵌套GridView时显示不全的问题。

    package com.yetu.ofmy; import android.view.MotionEvent; import android.widget.ListView; /** * * @Cla ...

  4. 计算机word显示不全,win7系统电脑打开Word文档内容显示不全或显示空白的解决方法...

    很多小伙伴都遇到过win7系统电脑打开Word文档内容显示不全或显示空白的困惑吧,一些朋友看过网上零散的win7系统电脑打开Word文档内容显示不全或显示空白的处理方法,并没有完完全全明白win7系统 ...

  5. 页面内容显示不全问题的解决办法

    页面内容显示不全,但不会出现滚动条(没有设置的情况下),可能出现的原因是因为html结构不完整.修改方法: <body style= "overflow:auto"> ...

  6. 没有滚动条,页面内容显示不全问题的解决方法

    页面内容显示不全,但不会出现滚动条(没有设置的情况下),可能出现的原因是因为html结构不完整.修改方法: <body style= "overflow:auto"> ...

  7. 超简单调整Fedora25遇到的字体小问题——字体渲染问题和输入框内容显示不全...

    第一个问题:字体渲染 抗锯齿效果很不舒服.如图: 锯齿很明显.解决方法,使用gnome-tweak-tool(中文名:优化工具)如果没有,请安装: dnf install -y gnome-tweak ...

  8. python spyder跑出的数据部分有些不变是怎么回事_解决Python spyder显示不全df列和行的问题...

    python中有的df列比较长head的时候会出现省略号,现在数据分析常用的就是基于anaconda的notebook和sypder,在spyder下head的时候就会比较明显的遇到显示不全.这时候我 ...

  9. python中df head_解决Python spyder显示不全df列和行的问题

    python中有的df列比较长head的时候会出现省略号,现在数据分析常用的就是基于anaconda的notebook和sypder,在spyder下head的时候就会比较明显的遇到显示不全.这时候我 ...

最新文章

  1. tp5中mysql使用REGEXP 正则匹配
  2. bit索引 mysql_Mysql优化之索引实现原理
  3. 一句DOS命令搞定文件合并
  4. Java 数组获取最大值和最小值
  5. CSDN怎么换行?添加空行
  6. numpy的sum函数、mean函数
  7. 云课堂智慧职教网页版登录入口_云课堂智慧职教网页版登录入口
  8. TP-LINK无线网卡免驱版 安装使用问题整理
  9. 像素值,像素坐标,灰度值
  10. 帆软报表日期控件默认值为空
  11. 上海市职称英语计算机报名,全国职称计算机考试
  12. js实现直接打印pdf文件内容解决方案
  13. 只有你能听见(Calling you)2
  14. 使用VBA实现xls批量转xlsx(遍历当前文件夹以及子文件夹)
  15. 外贸业务员该如何拓客?
  16. springboot + Vue 整合阿里云视频点播 | Spring Boot 20
  17. 2020年烟花爆竹经营单位主要负责人试题及答案及烟花爆竹经营单位主要负责人实操考试视频
  18. Vue2 的 diff 算法
  19. 优化了一个SQL---纪念一下
  20. Windows XP系统修复功能的具体操作方法

热门文章

  1. .NET MVC过滤器ActionFilterAttribute验证权限以及Model
  2. (附源码)基于SSM的自习室管理系统 毕业设计201524
  3. 天线开路短路检测原理_为什么有好多天线的阵子都是短路结构的?
  4. Sketch如何将文字转成图片或轮廓
  5. docker容器中安装vim
  6. SDL2的学习之路<一> 创建基本窗口
  7. 教育大数据总体解决方案(4)
  8. 真无线蓝牙耳机排行榜:运动蓝牙耳机品牌推荐
  9. 登陆linux主机提示all,修改 linux 的命令行提示符PS1-限制IP通过SSH登陆linux服务器-linux下系统服务详解_169IT.COM...
  10. 狼叔:Node全栈为前端带来更多可能