首页 > 代码库 > 带有ListView的界面无法通过手势左右滑动切换界面问题解决办法

带有ListView的界面无法通过手势左右滑动切换界面问题解决办法

带有ListView的界面无法通过手势左右滑动切换界面问题解决办法

问题描述:

       在做OnGestureListener滑动切换窗口的时候,会遇到这样的问题。就是当界面中含有ListView的时候,OnGestureListener的左右触屏滑动就被ListView自己吃掉了。

问题分析:

       在Android系统中,事件的分发和响应都按照一定的优先级仅仅有条的进行着。如果Activity中包含ListView那么系统的onTouchEvent事件会优先分发给ListView去处理,这时ListViewOnItemClickListener监听器会优先响应onTouchEvent事件。从而导致GestureDetector无法接收到系统的onTouchEvent事件。

解决方法:

 解决方法主要有两种:

第一种:改变系统分发的onTouchEvent事件的顺序。这种方式比较简单。

第二种:自定义ListView使其支持GestureDetectorOnGestureListener。这种方式相对于第一种方式比较复杂。

下面就具体介绍两种方式的在具体做法。

第一种:改变系统分发的onTouchEvent事件的顺序:

/**
 * 重写此方法将触控事件优先分发给GestureDetector,以解决滑动ListView无法切换屏幕的问题、
 * */
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    // TODO Auto-generated method stub    
    this.gestureDetector.onTouchEvent(ev);
    return super.dispatchTouchEvent(ev);
}

第二种:自定义ListView使其支持GestureDetectorOnGestureListener

第一步:自定义ListView

/**
 *自定义带有手势的listview,
 */
class GestureList extends ListView {
    int flag=BaseActivity.flag;
    Context context;
    GestureDetector gestureDetector;
    /**
     * 在xml布局里面使用GestureList,默认的会调用这个构造方法
     * @param context
     * @param attrs
     */
    public GestureList(Context context, AttributeSet attrs) {
       super(context, attrs);
       // TODO Auto-generated constructor stub
       this.context=context;
       gestureDetector=new GestureDetector(context,new Gesture(context));      
    }
    public GestureList(Context context, AttributeSet attrs, int defStyle) {
       super(context, attrs, defStyle);
       // TODO Auto-generated constructor stub
       this.context=context;
       gestureDetector=new GestureDetector(context,new Gesture(context));
    }
    public GestureList(Context context) {
       super(context);
       // TODO Auto-generated constructor stub
       this.context=context;
       gestureDetector=new GestureDetector(context,new Gesture(context));
    }
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
      
       if(gestureDetector.onTouchEvent(ev)) return true;
       return super.onTouchEvent(ev);
    }  
}
 

第二步:为自定义的ListView创建手势监听器:

public class Gesture implements OnGestureListener{
         /**得到全局的标志位**/     
         int flag=BaseActivity.flag;
         /**要切换有切换的activity的个数**/
         int length=BaseActivity.myClass.length;
         @SuppressWarnings("rawtypes")
         /**得到activity数组 **/
         Class[] myClass=BaseActivity.myClass;
         Context context;
         public Gesture(Context context) {
                   // TODO Auto-generated constructor stub
                   this.context=context;
         }
         @Override
         public boolean onDown(MotionEvent e) {
                   // TODO Auto-generated method stub
                   return false;
         }
 
         @Override
         public void onShowPress(MotionEvent e) {
                   // TODO Auto-generated method stub
                  
         }
         @Override
         public boolean onSingleTapUp(MotionEvent e) {
                   // TODO Auto-generated method stub
                   return false;
         }
         @Override
         public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                            float distanceY) {
                   // TODO Auto-generated method stub
                   return false;
         }
         @Override
         public void onLongPress(MotionEvent e) {
                   // TODO Auto-generated method stub
                  
         }
         @Override
         /**
          * 滑动事件的处理
          */
         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                            float velocityY) {                 
             //左滑动
        if (e1.getX() - e2.getX() > 50) { 
                 Log.i("Fling", "Gesture:左滑动 "); 
                 if (++flag>=length) {
                                     flag=length-1;
                                     //改变BaseActivity,让其知道标志位改变了
                     BaseActivity.flag=flag;
                                     return true;
                            }       
                 BaseActivity.flag=flag;
            Intent intent=new Intent(context, myClass[flag]);
            //用这个FLAG启动的Activity,一旦退出,就不会存在于栈中
            intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY|Intent. FLAG_ACTIVITY_REORDER_TO_FRONT);
            //需要context才能启动activity
            context.startActivity(intent);             
            return true; 
        }
        //右滑动
        else if (e2.getX() - e1.getX()>50) {
                 Log.i("Fling", "Gesture:右滑动 "); 
                    if (--flag<0) {
                                     flag=0;
                                     //改变BaseActivity,让其知道标志位改变了
                     BaseActivity.flag=flag;
                                     return true;
                            }       
                    BaseActivity.flag=flag;
            Intent intent=new Intent(context,myClass[flag]);
           //用这个FLAG启动的Activity,一旦退出,就不会存在于栈中
            intent.setFlags(Intent. FLAG_ACTIVITY_NO_HISTORY|Intent. FLAG_ACTIVITY_REORDER_TO_FRONT);
            //需要context才能启动activity
            context.startActivity(intent); 
//                   System.exit(0);//退出当前Activity                   
            return true; 
        } 
        return true; 
         }
}
 

第三步:在布局界面引用自定义的ListView

<com.jph.custom.GestureList android:id="@+id/list"
    android:layout_height="match_parent"
    android:layout_width="wrap_content"
    android:focusable="false"
    />