问题:嵌套的时候却发现listview本来一次性请求有10条数据却显示一条甚至还不完整,并且滑动listview只能在显示一条数据的空间高度上滑动。造成这种结果的原因是scrollview作为父级滑动控件,listview作为孩子,那么scrollview便会把listview的滑动效果给消费掉,造成listview不知道自身该有多高,也就不能展开了。
1.动态计算listview的高度
/** * 动态设置ListView的高度 * @param listView */ private void setListViewHeightBasedOnChildren(ListView listView) { if(listView == null) return; 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); }
说明:这个方法的话,item必须是LinearLayout,是利用LinearLayout的measure()方法来测量的,可以在子项比较少的时候用。太多的话,不适合。另外,会有个小问题:显示的时候先显示的是listview的首项,而不是scrollview的顶部。所以,视图实例后现将scrollview滑动到顶端。如下代码:
scrollview = (ScrollView) findViewById(R.id.scrollview); scrollview.smoothScrollTo(0, 0);
2.自定义listview重写onMeasure()方法
public class ListViewForScrollView extends ListView { public ListViewForScrollView(Context context) { super(context); } public ListViewForScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public ListViewForScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
3.整体只用一个ListView滑动组件
我们知道listview里面有addHeaderView(),addFooterView(),addView()。可以利用三个方法在合适的时候将相应部分的数据添加进去,另外listview的所有属性都可以使用,包括重用机制。
另外:如何解决ListView底部或者头部分割线不显示的问题。代码如下:
listView.addHeaderView(new View(this)); listView.addFooterView(new View(this));(因为android:headerDividersEnabled、 android:footerDividersEnabled这两个属性默认就是为true的,因此就不需要在xml中设置这两个属性,它们的意思是:在footerview之前是否添加分割线,默认为true)