一,按

在开发中,最近常遇到这个UI的结构,遇到了不少问题,如下:

1, listview的高度不对

2, 页面闪动,不在最开始的位置

3, 如果listview的item需要改变高度,listview的高度不能正常更新

 

二,解决方案一:动态计算listview高度

1, 具体函数请百度之,原理就是item高度加上divider高度

2, 局限:

2-1 使用麻烦,需要listview可能改变的地方调用

2-2 页面在部分机型上,仍然存在闪动的问题

3, 参考代码如下:

 

public 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();    
         }    
  
         System.out.println("aaa==="+totalHeight);  
         ViewGroup.LayoutParams params = listView.getLayoutParams();    
         params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));    
         listView.setLayoutParams(params);    
    }

三,解决方案二:使用自定义Listview

1, 使用自定义ListView,修改onMeasure()方法即可

参考代码如下:

 

public class InScrollListView extends ListView{

	public InScrollListView(Context context) {
		super(context);
	}
	
	public InScrollListView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	
	public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
		super.onMeasure(widthMeasureSpec, expandSpec);
	}
}

2, 局限:

2-1 页面在部分机型上,仍然存在闪动的问题

2-2 如果有点击事件需要修改item的高度,则需要wapper一层,具体实现方式就是将item是否是展开的状态,包在数据结构中。点击事件之后,update data,然后再notify adapter

 

四,解决方案三:利用Listview的Header (推荐方案)

1, 拆解页面view,采用addHeader(View v)的方法将view加到listview中去。

2, 局限:

2-1 相对麻烦一些,但是实现效果是最好的。另外一个优点是,魅族机器上,scrollview滑动会有很奇怪的问题,换成Listview之后,也不存在这个问题。


3,  可能会遇到的问题

3-1 head view真正被加入listview的时机是setAdapter之后

3-2 控制head view的显示,可以才从内置wrapperlayout来处理