转自:http://www.cnblogs.com/gzgg/archive/2011/12/17/2291265.html
前几天因为项目的需要,要在一个ListView中放入另一个ListView,也即在一个ListView的每个ListItem中放入另外一个ListView。但刚开始的时候,会发现放入的小ListView会显示不完全,它的高度始终有问题。上网查了下,发现别人也有遇到这样的问题,而大多数人都不推荐这样的设计,因为默认情况下Android是禁止在ScrollView中放入另外的ScrollView的,它的高度是无法计算的。对于这个问题现有三种解决方法:
第一种:
在正屏幕中,屏幕的上方有些概要信息需要显示,下方有个列表信息需要显示,而因为概要信息已经占用了1/3的屏幕高度,而现在想在下面列表滚动的时候上面的概要信息随着滚动隐藏,就好像概要信息和下面的列表信息都是在一个列表里面一样,这个时候可以将概要信息包裹在一个ViewGroup中,然后使用LIstView.addHead(View)方法添加到列表中即可。
第二种:
它的思路就是在设置完ListView的Adapter后,根据ListView的子项目重新计算ListView的高度,然后把高度再作为LayoutParams设置给ListView,这样它的高度就正确了,以下是具体的代码编写:
public class Utility { public static void setListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { // pre-condition 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); } }
虽然在ScrollView中显示ScrollView在技术上的难题可以攻破,但是这样的设计却是非常差的用户体验因为用户会不容易看到和操作子ScrollView中的内容。比如好的设计是,父ListView的每个Item只显示概括性的描述,然后点击其Item会进入另外一个页面来详细描述和展示以及对这个Item的操作
以上可以解决scrollView内嵌listView,但是有一个问题是第一次进入界面时动态加载listview的items后页面会跳转到listview的第一个子项,这很蛋疼,
无奈又不知道怎么解决,就先用如下方法进行解决:
scrollView.post(new Runnable() { //让scrollview跳转到顶部,必须放在runnable()方法中 @Override public void run() { scrollView.scrollTo(0, 0); } });
第三种:
第三种和第二种的思路是一样的,只是实现方式不同,它是自定义ListView,重载onMeasure()方法,设置全部显示。
public class ScrollViewWithListView extends ListView { public ScrollViewWithListView(android.content.Context context,android.util.AttributeSet attrs) { <span style="white-space:pre"> </span>super(context, attrs); } /** * Integer.MAX_VALUE >> 2,如果不设置,系统默认设置是显示两条 */ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { <span style="white-space:pre"> </span>int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST); <span style="white-space:pre"> </span>super.onMeasure(widthMeasureSpec, expandSpec); } }