常用的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. 在线预览office文件

    Office Online 实现在线预览 office的在线预览,针对不同的浏览器版本和系统具有要求,具体的相关文档请参考官方文档. 利用office online 平台进行office 文档的在线查 ...

  2. Java 干货之深入理解Java内部类

    可以将一个类定义在另一个类或方法中,这样的类叫做内部类 --<Thinking in Java> 说起内部类,大家并不陌生,并且会经常在实例化容器的时候使用到它.但是内部类的具体细节语法, ...

  3. Codeforces 1178G. The Awesomest Vertex

    传送门 首先通过dfs序把子树操作转化为区间操作,求最大值可以用斜率优化. 然后分个块,对每个块维护个凸包.修改时中间的打个标记,边角暴力重构:询问时中间的用斜率优化的方法求,边角的暴力求. 由于此题 ...

  4. Java自动化测试框架-12 - TestNG之xml文件详解篇 (详细教程)

    1.简介 现在这篇,我们来学习TestNG.xml文件,前面我们已经知道,TestNG就是运行这个文件来执行测试用例的.通过本篇,你可以进一步了解到:这个文件是配置测试用例,测试套件.简单来说,利用这 ...

  5. dubbo监控安装

    tar xf dubbo-monitor-simple-2.8.4-assembly.tar.gz cd dubbo-monitor-simple-2.8.4 vi conf/dubbo.proper ...

  6. 关闭redis持久化功能

    关闭redis持久化功能持久化会报如下信息 会影响硬盘写入性能 所以没什么用 就关掉吧 修改redis配置文件,redis.conf 第115行左右. 1.注释掉原来的持久化规则 <pre> ...

  7. html部分知识点(待完善)

    html部分知识点 跳转 在A页面某链接处`<a href="#aa" target="_blank"></a> 在B页面指定的标题处定 ...

  8. 【集合系列】- 深入浅出分析LinkedHashMap

    一.摘要 在集合系列的第一章,咱们了解到,Map的实现类有HashMap.LinkedHashMap.TreeMap.IdentityHashMap.WeakHashMap.Hashtable.Pro ...

  9. spark基于yarn的两种提交模式

    一.spark的三种提交模式 1.第一种,Spark内核架构,即standalone模式,基于Spark自己的Master-Worker集群. 2.第二种,基于YARN的yarn-cluster模式. ...

  10. OFFICE 2010 每次打开提示安装的问题

    OFFICE2010 安装后每次打开 文件总是提示配置 解决办法: 前提是office已经激活 注册表找到 HKEY_CURRENT_USER\Software\Microsoft\Office\14 ...