Android ListView的header footer设置visibility gone不起作用
常用的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不起作用的更多相关文章
- Android ListView的item背景色设置以及item点击无响应等相关问题
Android ListView的item背景色设置以及item点击无响应等相关问题 在Android开发中,listview控件是非常常用的控件,在大多数情况下,大家都会改掉listview的ite ...
- [Android Bug] ListView中Header, Footer无法隐藏(gone)的问题
ListView中Header.Footer View应该是会应该遇到, 比如说,滚动到底部时,自动开始加载: 对于一些应用市场,会在Header中加上ViewFlipper做应用推荐(滚动的那种,好 ...
- delphi xe6 android ListView增加 Header或Footer 的方法
var Item1: TListViewItem;begin Item1 := ListView1.Items.Add; Item1.Purpose:=TListItemPurpose. ...
- Android ListView的item背景色设置
1.如何改变item的背景色和按下颜色 listview默认情况下,item的背景色是黑色,在用户点击时是黄色的.如果需要修改为自定义的背景颜色,一般情况下有三种方法: 1)设置listSelecto ...
- [Android]ListView中分割线的设置
1.在布局文件中ListView元素中通过属性设置 android:divider="#fffff" 分割线颜色 android:dividerHeight="1px& ...
- Android ListView中按钮监听器设置的解决方案
在做安卓应用开发的时候很经常会用到ListView,并且每一个Item里面都会有按钮之类的需要进行事件监听的控件.在给按钮添加OnClickListener的时候,一开始很下意识的会想在ListVie ...
- android listview 三种适配器设置
1: public class ArrayAdapterActivity extends ListActivity { @Override public void onCreate(Bundle sa ...
- Android ListView自定义分割线 header 和footer设置没有页眉和页脚
ListView.setFooterDividersEnabled(false);//设置listview无页脚 ListView.setHeaderDividersEnabled(false);// ...
- 【我的Android进阶之旅】如何去除ListView中Header View、Footer View中的分割线
最近的项目中给ListView 加入了一个Header View之后,发现Header View的下方也有了分割线,很难看,UI要求将Header View的分割器去掉,好吧.现在就来说一说如何如何去 ...
随机推荐
- xtrabackup备份原理及流式备份应用
目录 xtrabackup备份原理及流式备份应用 0. 参考文献 1. xtrabackup 安装 2. xtrabackup 备份和恢复原理 2.1 备份阶段(backup) 2.2 准备阶段(pr ...
- 使用memset初始化int数组
memset()是一个来自于string库的函数,正规用法是初始化char类型的数组.因为char类型只占1个字节,memset按字节赋值后,会将char类型数组的所有元素变为你指定的值.但是4字节的 ...
- 【Java必修课】String.intern()原来还能这么用(原理与应用)
1 简介 String.intern()是JDK一早就提供的native方法,不由Java实现,而是底层JVM实现,这让我们对它的窥探提高了难度.特别是在Oracle收购了Sun公司后,源代码不开源了 ...
- NOIP模拟测试25
这次考试后面心态爆炸了...发现刚了2h的T2是假的之后就扔掉了,草率地打了个骗分 T1只会搜索和m=0 最先做的T3,主要是发现部分分很多,当时第一眼看上去有87分(眼瞎了). 后来想了想,感觉一条 ...
- Python - selenium自动化-Chrome(headless)
什么是 Headless Chrome Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序.相比于现代浏览 ...
- 『题解』Codeforces9D How many trees?
更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description In one very old text file there was wr ...
- 『题解』洛谷P5015 标题统计
题意描述 给你一个字符串,求所有字符的总数. 字符只包含数字,大小写字母. 分析 字符串的长度还是\(\le5\)的. 直接枚举就可以了. AC代码: NOIP官方标准程序是这样的 #include ...
- Spring 框架常用语法进行总结
Spring 框架常用语法进行总结: spring框架的二大主要的功能就是IOC和AOP. IOC: 控制反转(依赖注入) AOP: 面向切面编程 学习spring最好的方法就是去看官网,里面有详细的 ...
- java 实现一个死锁
/** * 死锁:两个或多个线程在执行过程中,相互争夺资源而造成的一种互相等待的现象 * 实现一个死锁 * <p> * <p> * 查看死锁 * 1. 在当前类的文件夹下,打开 ...
- Typings移除Deprecated Warning
使用TypeScript进行开发中,经常遇到如下的Deprecated Warning.虽然没有实际影响,但看多了,确实挺烦. 要想消除这些Warning,需要以下几个步骤: 步骤一,确认Warnin ...