昨天开发遇到一个很诡异的问题,项目中需要在一个listview中嵌套另外一个listview,但是不管怎么设置,内部的listview总是只显示一项。后来终于搞明白,原因是在控件绘制出来之前要对ListView的大小进行measure,问题就出在内部listview的测量阶段,只需要在onMeasure()函数中对listview的高度重新measure就可以了。我们需要继承ListView控件,然后重写它的onMeasure方法,如下:
@Override
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
我们指定了一个很大的值,因为我们不知道我们的listview具体有多高,所以使用了最大模式MeasureSpec.AT_MOST,它表示listview的最大高度为Integer.MAX_VALUE >> 2,如果listview显示的高度小于这个值,就显示其实际的高度。
这种方法可以使内部的listview全部显示出来,但是它是不能单独滚动的,只能随着外部的listview一起滚动。
从网上看到还有另外一种方式也可以达到这个效果,它是在设置了listview的adpater之后,根据当前listview的item的项数来计算它的实际高度,这个值是确定的。具体的方法如下:
- /**
- * 设置Listview的高度
- */
- public void setListViewHeight(ListView listView) {
- ListAdapter listAdapter = listView.getAdapter();
- if (listAdapter == null) {
- return;
- }
- int totalHeight = 0;
- for (int i = 0; i < listAdapter.getCount(); i++) {
- View listItem = listAdapter.getView(i, null, listView);
- listItem.measure(0, 0);
- totalHeight += listItem.getMeasuredHeight();
- }
- ViewGroup.LayoutParams params = listView.getLayoutParams();
- params.height = totalHeight + (listView.getDividerHeight() *
- (listAdapter.getCount() - 1));
- listView.setLayoutParams(params);
- }