常用的ViewGroup,例如LinearLayout,在onMeasure方法内对每个child view执行measure前,会判断child view的visibility是否为gone。如果是gone,则不对这个child view执行measure操作,即这个child view的高度不被计算在linearLayout的高度里面。LinearLayout的measureVertical代码片段:

if (child.getVisibility() == View.GONE) {
i += getChildrenSkipCount(child, i);
continue;
}

  

  view在measure自己时,并不会去判断自己的Visibility是GONE。这个逻辑操作如上述代码所示,是在parent view里面做的。所以当对LinearLayout里面的一个childView设置Visiblility为gone时,这个view不会被measure,最终也不会被显示出来。

  在使用ListView时,经常会添加一些headerView、footerView。但是当设置headerView、footerView的visibility为gone时,却发现headerView、footerView虽然没有显示出来,但垂直方向其所占的位置还是被显示出来了,从而出现了空白区域。网上查到的解决办法是:不能直接设置headerView、footerView的Visibility为gone。而是要在HeaderView、FooterView外面包一层parent view(FrameLayout RelativeLayout 都可以),并设置layout_height=“wrap_content”。然后对里面的childView设置visibility为GONE、VISIBLE都会生效。查看源码,情况确实如此。

  ListView的onMeasure里面,如果ListView的widthMode、heightMode有一个是unspecified时(应该对应于在XML中没有对listView设置layout_width、layout_height),会调用方法measureScrapChild。如果没有unspecified的情况,则会调用measureHeightOfChildren方法,而此方法内部也会调用measureScrapChild方法。查看measureScrapChild方法:

private void measureScrapChild(View child, int position, int widthMeasureSpec) {
LayoutParams p = (LayoutParams) child.getLayoutParams();
if (p == null) {
p = (AbsListView.LayoutParams) generateDefaultLayoutParams();
child.setLayoutParams(p);
}
p.viewType = mAdapter.getItemViewType(position);
p.forceAdd = true; int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
mListPadding.left + mListPadding.right, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}

  可以看出,listview在对child view执行measure前,没有判断visibility为gone的情况

  再看看里面的详细逻辑:

  • lpHeight>0时,说明在xml或者程序里面设置了一个确定的尺寸,这里没有问题;
  • else里面,设置mode为UNSPECIFIED,就是让child view自己去决定大小,child view在measure自己时,不会考虑VISIBILITY属性。

  else包含的逻辑:

  • lpHeight == 0:对应于在xml或者代码中设置尺寸为0,说明也是不起作用的,最终还是会显示出空白
  • lpHeight == -1:MATCH_PARENT
  • lpHeight == -2:WRAP_CONTENT

  三种情况,都会根据view实际的内容返回一个wrap_content的尺寸。这里就解释了为何设置headerView、footerView的visibility为gone时,会出现空白区域。

  如果外面包一层parent view(例如LinearLayout),并设置layout_height为wrap_content(按上面的分析,设置match_parent也是可以的),listView会调用调用额外的这个parent view的measure方法。而LinearLayout在measure时,会判断child view的visibility,如果为gone,则会返回0.最终这个额外的parent view返回给list view的尺寸就是0,从而解决了空白区域的问题。

  这个问题算是listview的一个feature吧!

Android ListView的header footer设置visibility gone不起作用的更多相关文章

  1. Android ListView的item背景色设置以及item点击无响应等相关问题

    Android ListView的item背景色设置以及item点击无响应等相关问题 在Android开发中,listview控件是非常常用的控件,在大多数情况下,大家都会改掉listview的ite ...

  2. [Android Bug] ListView中Header, Footer无法隐藏(gone)的问题

    ListView中Header.Footer View应该是会应该遇到, 比如说,滚动到底部时,自动开始加载: 对于一些应用市场,会在Header中加上ViewFlipper做应用推荐(滚动的那种,好 ...

  3. delphi xe6 android ListView增加 Header或Footer 的方法

    var  Item1: TListViewItem;begin    Item1 := ListView1.Items.Add;    Item1.Purpose:=TListItemPurpose. ...

  4. Android ListView的item背景色设置

    1.如何改变item的背景色和按下颜色 listview默认情况下,item的背景色是黑色,在用户点击时是黄色的.如果需要修改为自定义的背景颜色,一般情况下有三种方法: 1)设置listSelecto ...

  5. [Android]ListView中分割线的设置

    1.在布局文件中ListView元素中通过属性设置 android:divider="#fffff"  分割线颜色 android:dividerHeight="1px& ...

  6. Android ListView中按钮监听器设置的解决方案

    在做安卓应用开发的时候很经常会用到ListView,并且每一个Item里面都会有按钮之类的需要进行事件监听的控件.在给按钮添加OnClickListener的时候,一开始很下意识的会想在ListVie ...

  7. android listview 三种适配器设置

    1: public class ArrayAdapterActivity extends ListActivity { @Override public void onCreate(Bundle sa ...

  8. Android ListView自定义分割线 header 和footer设置没有页眉和页脚

    ListView.setFooterDividersEnabled(false);//设置listview无页脚 ListView.setHeaderDividersEnabled(false);// ...

  9. 【我的Android进阶之旅】如何去除ListView中Header View、Footer View中的分割线

    最近的项目中给ListView 加入了一个Header View之后,发现Header View的下方也有了分割线,很难看,UI要求将Header View的分割器去掉,好吧.现在就来说一说如何如何去 ...

随机推荐

  1. 最强中文NLP预训练模型艾尼ERNIE官方揭秘【附视频】

    “最近刚好在用ERNIE写毕业论文” “感觉还挺厉害的” “为什么叫ERNIE啊,这名字有什么深意吗?” “我想让艾尼帮我写作业” 看了上面火热的讨论,你一定很好奇“艾尼”.“ERNIE”到底是个啥? ...

  2. 一 :Mysql基础

    1.Mysql初识 三高角度引入 三高:高并发,高可用,高性能. why: 1.1数据文件和程序不应该放在同一台机器上!一旦机器挂了,数据和程序全都挂了不能对外提供服务,高可用性差. 1.2纵向扩展有 ...

  3. Airy Memory 内存清理 + 注册码

    链接: https://pan.baidu.com/s/1ZGxDtJBMhrRtBISvL1Lv0w 提取码: ccjs

  4. SpringBoot 整合 Elasticsearch深度分页查询

    es 查询共有4种查询类型 QUERY_AND_FETCH: 主节点将查询请求分发到所有的分片中,各个分片按照自己的查询规则即词频文档频率进行打分排序,然后将结果返回给主节点,主节点对所有数据进行汇总 ...

  5. AtCoder Grand Contest 038

    目录 \(\bf A - 01 \ Matrix\) \(\bf B- Sorting \ a \ Segment\) \(\bf C-LCMs\) \(\bf D-Unique \ Path\) 这 ...

  6. 大数据之路day01_1--Java下载、安装等配置

    从今天开始,我就正式的走上大数据的道路了,如果说我为啥要去学习大数据,可能我的初衷是以后可以接触到人工智能方面的技术,后来在自学的过程中发现,学习人工智能,需要扎实的算法,以及对大量数据的处理,再者, ...

  7. Opencv python(3)| cv. VideoCapture.get() 参数介绍

    cv2.VideoCapture.get ()  的 (0-18)参数 cv2.VideoCapture.get(0)            视频文件的当前位置(播放)以毫秒为单位 cv2.Video ...

  8. 生活问题 | 对华为畅玩手机5X进行升级

    步骤一:准备一张SD卡,建议使用Sandisk, Kingstone, 或Kingmax,大小建议在2G KIW-AL10C00B258 软件版本升级指导书 Secret  2016-11-25 Hu ...

  9. Python——标识符的命名规则

    01 Python语言的特点 python的语言特点有很多,我们这里只讲一点,python是一门面向对象的语言,即一切皆对象(Linux中有一句是:一切皆文件),括号内的只是打个比方,不懂也没事,就是 ...

  10. python基础-面向过程编程

    面向过程编程 面向过程编程其实是一种机械式的思维方式,其核心就是"过程". 过程指的是一种解决问题的步骤,即先干什么再干什么,最后干什么. 优点:将复杂的问题流程化,进而简单化. ...