android listview header高度,Android Listview设置Header或Footer隐藏后Header或Footer占位问题?...

在Android开发中,会经常遇到给ListView添加自定义的HeaderView或FooterView,如果我们想隐藏HeaderView或FooterView的时候,一般会调用view的setVisibility方法设置属性值GONE,这时候发现View元素虽然正常的被隐藏了,但是view所占的高度却没有被改变,view所占的位置还是被显示了出来,从而出现一片空白区域

解决思路:

解决问题之前首先需要明白为什么会出现这个问题?

通过源码可以看到,在常用的ViewGroup,例如LinearLayout,在onMeasure方法中对每个childView执行measure前,都会判断childView的visibility是否为GONE,如果是GONE,则不对这个childView执行meaure操作,也就是这个childView的高度不会被计算到LinearLayout的高度中,下面是LinearLayout中onMeasure方法的代码片段:

// See how tall everyone is. Also remember max width.

for (int i = 0; i < count; ++i) {

final View child = getVirtualChildAt(i);

if (child == null) {

mTotalLength += measureNullChild(i);

continue;

}

if (child.getVisibility() == View.GONE) {

i += getChildrenSkipCount(child, i);

continue;

}

。。。

但是view在measure自己的时候,并不会去判断自身的visibility是否为GONE,也就是只有在parentView中才会去判断,所以当对LinearLayout里面的一个子View设置Visibility为GONE时,这个View是不会被measure的,最终也是不会被显示的。

了解了常用ViewGroup是如何测量宽高的,再来看一下ListView里面是如何测量的,通过阅读源码可以看到如果ListView的widthMode、heightMode任意一个是unspecified时,就会调用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在对ChildView执行meaure之前,并没有判断visibility为GONE的情况,当lpHeight > 0 时,说明在xml布局文件中给ListView设置过了一个尺寸值,所以不会出现问题,而在else里面,设置mode为UNSPECIFIED,目的就是为了让ChildView自己去测量大小,而ChildView在measure自己时是不会考虑visibility情况的,看到这里也就明白了为什么在设置HeaderView或FooterView的visibility为GONE时,会出现空白了!

解决方法:

弄明白了原因以后就知道该如何解决这个问题了,不能直接设置HeaderView或FooterView的visibility为GONE,而是需要在HeaderView或FooterView外层嵌套一层parentView,并且设置这个ParentView的layout_height="wrap_content",然后对里面的childView设置visibility为GONE或VISIBLE就会解决这个问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值