同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" />
版权声明:本文博客原创文章。博客,未经同意,不得转载。