在一个滑动控件或者是布局里面,添加另外一个可以滑动的控件,通常会造成一些莫名其妙的问题。今天主要介绍在工作中遇到的,在ScrollView布局中嵌套Listview显示不正常,和在Listview中嵌套Listview的滑动冲突的问题。
1.ScrollView布局中嵌套Listview显示不正常的解决方案
目前来说,解决这个问题有好几种解决方案,这里只介绍其中两种比较简单易行的其中两种。
(1)自定义一个Listview,继承自Listview,代码如下:
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); } }
在使用的时候,用这个控件代替Listview控件即可。
(2)重新计算Listview的高度
在一个滑动布局中添加一个滑动控件,滑动控件的高度因为不能计算,所以只能显示一个Item,若要解决这个问题,我们可以重新计算Listview的高度,调用下面的静态方法即可。
/** * scrollview嵌套listview显示不全解决 * * @param listView */ public static void setListViewHeightBasedOnChildren(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); }
2.在Listview中嵌套Listview的滑动冲突问题
之前在项目中,出现了这种需求,就是在一个listview的footer中添加一个小的Listview,但是由于触摸冲突问题,小的listview不能滑动,若要解决这个问题,我们可以自定义一个控件继承自listview,然后重写onInterceptTouchEvent方法,对触摸事件进行分发。
onInterceptTouchEvent()是ViewGroup的一个方法,目的是在系统向该ViewGroup及其各个childView触发onTouchEvent()之前对相关事件进行一次拦截,我们可以在这个方法里面,对子控件或者是父控件获取触摸处理权限进行分发,从而完成各自的滑动任务。
效果图如下
代码如下
/** * * @ClassName: com.example.listdemo.InnerListview * @Description: 可以放在Listview中的Listview * @author zhaokaiqiang * @date 2014-8-15 下午2:43:34 * */ public class InnerListview extends ListView { public InnerListview(Context context) { super(context); } public InnerListview(Context context, AttributeSet attrs) { super(context, attrs); } public InnerListview(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { // 当手指触摸listview时,让父控件交出ontouch权限,不能滚动 case MotionEvent.ACTION_DOWN: setParentScrollAble(false); case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: // 当手指松开时,让父控件重新获取onTouch权限 setParentScrollAble(true); break; } return super.onInterceptTouchEvent(ev); } // 设置父控件是否可以获取到触摸处理权限 private void setParentScrollAble(boolean flag) { getParent().requestDisallowInterceptTouchEvent(!flag); } }
这样,外面的listview和里面的小listview就都可以实现各自的滑动了。
本文章出自http://blog.csdn.net/zhaokaiqiang1992,转载请说明!
解决ScrollView中嵌套Listview,Listview中嵌套Listview显示不完整和滑动冲突的问题