本文章出自http://blog.csdn.net/zhaokaiqiang1992,转载请说明!

 

在一个滑动控件或者是布局里面,添加另外一个可以滑动的控件,通常会造成一些莫名其妙的问题。今天主要介绍在工作中遇到的,在ScrollView布局中嵌套Listview显示不正常,和在Listview中嵌套Listview的滑动冲突的问题。

1.ScrollView布局中嵌套Listview显示不正常的解决方案

目前来说,解决这个问题有好几种解决方案,这里只介绍其中两种比较简单易行的其中两种。

(1)自定义一个Listview,继承自Listview,代码如下:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public class ListViewForScrollView extends ListView {  
  2.   
  3.     public ListViewForScrollView(Context context) {  
  4.         super(context);  
  5.     }  
  6.   
  7.     public ListViewForScrollView(Context context, AttributeSet attrs) {  
  8.         super(context, attrs);  
  9.     }  
  10.   
  11.     public ListViewForScrollView(Context context, AttributeSet attrs,  
  12.             int defStyle) {  
  13.         super(context, attrs, defStyle);  
  14.   
  15.     }  
  16.   
  17.     /** 
  18.      * 只需要重写这个方法即可 
  19.      */  
  20.     @Override  
  21.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  22.         int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,  
  23.                 MeasureSpec.AT_MOST);  
  24.         super.onMeasure(widthMeasureSpec, expandSpec);  
  25.     }  
  26.   
  27. }  

 

在使用的时候,用这个控件代替Listview控件即可。

 

(2)重新计算Listview的高度

在一个滑动布局中添加一个滑动控件,滑动控件的高度因为不能计算,所以只能显示一个Item,若要解决这个问题,我们可以重新计算Listview的高度,调用下面的静态方法即可。

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. /** 
  2.      * scrollview嵌套listview显示不全解决 
  3.      *  
  4.      * @param listView 
  5.      */  
  6.     public static void setListViewHeightBasedOnChildren(ListView listView) {  
  7.         ListAdapter listAdapter = listView.getAdapter();  
  8.         if (listAdapter == null) {  
  9.             return;  
  10.         }  
  11.   
  12.         int totalHeight = 0;  
  13.         for (int i = 0; i < listAdapter.getCount(); i++) {  
  14.             View listItem = listAdapter.getView(i, null, listView);  
  15.             listItem.measure(00);  
  16.             totalHeight += listItem.getMeasuredHeight();  
  17.         }  
  18.   
  19.         ViewGroup.LayoutParams params = listView.getLayoutParams();  
  20.         params.height = totalHeight  
  21.                 + (listView.getDividerHeight() * (listAdapter.getCount() - 1));  
  22.         listView.setLayoutParams(params);  
  23.     }  

 

 

2.在Listview中嵌套Listview的滑动冲突问题

之前在项目中,出现了这种需求,就是在一个listview的footer中添加一个小的Listview,但是由于触摸冲突问题,小的listview不能滑动,若要解决这个问题,我们可以自定义一个控件继承自listview,然后重写onInterceptTouchEvent方法,对触摸事件进行分发。

onInterceptTouchEvent()是ViewGroup的一个方法,目的是在系统向该ViewGroup及其各个childView触发onTouchEvent()之前对相关事件进行一次拦截,我们可以在这个方法里面,对子控件或者是父控件获取触摸处理权限进行分发,从而完成各自的滑动任务。

效果图如下

代码如下

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. /** 
  2.  *  
  3.  * @ClassName: com.example.listdemo.InnerListview 
  4.  * @Description: 可以放在Listview中的Listview 
  5.  * @author zhaokaiqiang 
  6.  * @date 2014-8-15 下午2:43:34 
  7.  *  
  8.  */  
  9. public class InnerListview extends ListView {  
  10.     public InnerListview(Context context) {  
  11.         super(context);  
  12.     }  
  13.   
  14.     public InnerListview(Context context, AttributeSet attrs) {  
  15.         super(context, attrs);  
  16.     }  
  17.   
  18.     public InnerListview(Context context, AttributeSet attrs, int defStyle) {  
  19.         super(context, attrs, defStyle);  
  20.   
  21.     }  
  22.   
  23.     @Override  
  24.     public boolean onInterceptTouchEvent(MotionEvent ev) {  
  25.         switch (ev.getAction()) {  
  26.         // 当手指触摸listview时,让父控件交出ontouch权限,不能滚动  
  27.         case MotionEvent.ACTION_DOWN:  
  28.             setParentScrollAble(false);  
  29.         case MotionEvent.ACTION_MOVE:  
  30.             break;  
  31.         case MotionEvent.ACTION_UP:  
  32.         case MotionEvent.ACTION_CANCEL:  
  33.             // 当手指松开时,让父控件重新获取onTouch权限  
  34.             setParentScrollAble(true);  
  35.             break;  
  36.   
  37.         }  
  38.         return super.onInterceptTouchEvent(ev);  
  39.   
  40.     }  
  41.   
  42.     // 设置父控件是否可以获取到触摸处理权限  
  43.     private void setParentScrollAble(boolean flag) {  
  44.         getParent().requestDisallowInterceptTouchEvent(!flag);  
  45.     }  
  46.   
  47. }  

 

这样,外面的listview和里面的小listview就都可以实现各自的滑动了。

 

    项目地址 https://github.com/ZhaoKaiQiang/InnerListview

 

arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()