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

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

问题描述:

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

问题分析:

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

解决方法:

解决方法主要有两种:

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

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

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

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

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

第二种: 自定义ListView使其支持 GestureDetector 的 OnGestureListener :

第一步:自定义 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"
    />
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值