requestDisallowInterceptTouchEvent

【Android】requestDisallowInterceptTouchEvent 

转自:http://www.cnblogs.com/lqminn/archive/2013/03/02/2940194.html

ViewPager来实现左右滑动切换tab,如果tab的某一项中嵌入了水平可滑动的View就会让你有些不爽,比如想滑动tab项中的可水平滑动的控件,却导致tab切换。

因为Android事件机制是从父View传向子View的,可以去检测你当前子View是不是在有可滑动控件等,决定事件是否拦截,但是这个麻烦,而且并不能解决所有的问题(必须检测触摸点是否在这个控件上面),其实有比较简单的方法,在你嵌套的控件中注入ViewPager实例(调用控件的getParent()方法),然后在onTouchEvent,onInterceptTouchEvent,dispatchTouchEvent里面告诉父View,也就是ViewPager不要拦截该控件上的触摸事件。

1 requestDisallowInterceptTouchEvent(true)

代码一般如下:


 1 public boolean onTouch(View v, MotionEvent event) {
 2     switch (event.getAction()) {
 3     case MotionEvent.ACTION_MOVE: 
 4         pager.requestDisallowInterceptTouchEvent(true);
 5         break;
 6     case MotionEvent.ACTION_UP:
 7     case MotionEvent.ACTION_CANCEL:
 8         pager.requestDisallowInterceptTouchEvent(false);
 9         break;
10     }
11 }

当用户按下的时候,我们告诉父组件,不要拦截我的事件(这个时候子组件是可以正常响应事件的),拿起之后就会告诉父组件可以阻止。

展开阅读全文

getParent().requestDisallowInterceptTouchEvent(true);无效

05-16

求助啊rn我贴出主要的代码rnviewPager = (ViewPager) findViewById(R.id.view_pager);rnviewPager.setAdapter(new AdvAdapter(picList, picList.size()));rnviewPager.setOnPageChangeListener(this);rnviewPager.setCurrentItem(0);rnrnviewPager中加入的是我重写的ImageView,可以放大缩小rnpublic class ZoomDragImageView extends ImageView rnrn private Handler handler;rn private int leftReturn, topReturn, rightReturn, bottomReturn;rnrn private Activity mActivity;rnrn private int screen_W, screen_H;// 可见屏幕的宽高度rnrn private int bitmap_W, bitmap_H;// 当前图片宽高rnrn private int MAX_W, MAX_H, MIN_W, MIN_H;// 极限值rnrn private int current_Top, current_Right, current_Bottom, current_Left;// 当前图片上下左右坐标rnrn private int start_Top = -1, start_Right = -1, start_Bottom = -1,rn start_Left = -1;// 初始化默认位置.rnrn private int start_x, start_y, current_x, current_y;// 触摸位置rnrn private float beforeLenght, afterLenght;// 两触点距离rnrn private float scale_temp;// 缩放比例rnrn /**rn * 模式 NONE:无 DRAG:拖拽. ZOOM:缩放rn * rn * @author zhangjiarn * rn */rn private enum MODE rn NONE, DRAG, ZOOMrnrn ;rnrn private MODE mode = MODE.NONE;// 默认模式rnrn private boolean isControl_V = false;// 垂直监控rnrn private boolean isControl_H = false;// 水平监控rnrn private ScaleAnimation scaleAnimation;// 缩放动画rnrn private boolean isScaleAnim = false;// 缩放动画rnrn private MyAsyncTask myAsyncTask;// 异步动画rnrn public ZoomDragImageView(Context context) rn super(context);rn // TODO Auto-generated constructor stubrn initHandle();rn rnrn private void initHandle() rn handler = new Handler() rnrn @Overridern public void handleMessage(Message msg) rn // TODO Auto-generated method stubrn setFrame(leftReturn, topReturn, rightReturn, bottomReturn);rn rnrn ;rn rnrn public void setmActivity(Activity mActivity) rn this.mActivity = mActivity;rn rnrn /** 可见屏幕宽度 **/rn public void setScreen_W(int screen_W) rn this.screen_W = screen_W;rnrn bitmap_W = screen_W;rn MAX_W = bitmap_W * 3;rn MIN_W = bitmap_W / 2;rn rnrn /** 可见屏幕高度 **/rn public void setScreen_H(int screen_H) rn this.screen_H = screen_H;rnrn bitmap_H = screen_H;rn MAX_H = bitmap_H * 3;rn MIN_H = bitmap_H / 2;rn rnrn /***rn * 设置显示图片rn */rn @Overridern public void setImageBitmap(Bitmap bm) rn super.setImageBitmap(bm);rn /** 获取图片宽高 **/rn bitmap_W = bm.getWidth();rn bitmap_H = bm.getHeight();rnrn MAX_W = bitmap_W * 3;rn MAX_H = bitmap_H * 3;rnrn MIN_W = bitmap_W / 2;rn MIN_H = bitmap_H / 2;rnrn rnrn @Overridern protected void onLayout(boolean changed, int left, int top, int right,rn int bottom) rn super.onLayout(changed, left, top, right, bottom);rn Log.e("aa", "top=" + top + ",bottom=" + bottom + ",left=" + leftrn + ",right=" + right);rn if (start_Top == -1) rn start_Top = top;rn start_Left = left;rn start_Bottom = bottom;rn start_Right = right;rn rnrn rnrn /***rn * touch 事件rn */rn @Overridern public boolean onTouchEvent(MotionEvent event) rn /** 处理单点、多点触摸 **/rn switch (event.getAction() & MotionEvent.ACTION_MASK) rn case MotionEvent.ACTION_DOWN:rn onTouchDown(event);rn break;rn // 多点触摸rn case MotionEvent.ACTION_POINTER_DOWN:rn onPointerDown(event);rn break;rnrn case MotionEvent.ACTION_MOVE:rn onTouchMove(event);rn break;rn case MotionEvent.ACTION_UP:rn mode = MODE.NONE;rn break;rnrn // 多点松开rn case MotionEvent.ACTION_POINTER_UP:rn mode = MODE.NONE;rn /** 执行缩放还原 **/rn [color=#FF0000]getParent().requestDisallowInterceptTouchEvent(true);[/color]rn if (isScaleAnim) rn doScaleAnim();rn rn break;rn rnrn return true;rn rnrn /** 按下 **/rn void onTouchDown(MotionEvent event) rn mode = MODE.DRAG;rnrn current_x = (int) event.getRawX();rn current_y = (int) event.getRawY();rnrn start_x = (int) event.getX();rn start_y = current_y - this.getTop();rnrn rnrn /** 两个手指 只能放大缩小 **/rn void onPointerDown(MotionEvent event) rn if (event.getPointerCount() == 2) rn mode = MODE.ZOOM;rn beforeLenght = getDistance(event);// 获取两点的距离rn rn rnrn /** 移动的处理 **/rn void onTouchMove(MotionEvent event) rn int left = 0, top = 0, right = 0, bottom = 0;rn /** 处理拖动 **/rn if (mode == MODE.DRAG) rnrn /** 在这里要进行判断处理,防止在drag时候越界 **/rnrn /** 获取相应的l,t,r ,b **/rn left = current_x - start_x;rn right = current_x + this.getWidth() - start_x;rn top = current_y - start_y;rn bottom = current_y - start_y + this.getHeight();rnrn /** 水平进行判断 **/rn if (isControl_H) rn if (left >= 0) rn left = 0;rn right = this.getWidth();rn rn if (right <= screen_W) rn left = screen_W - this.getWidth();rn right = screen_W;rn rn else rn left = this.getLeft();rn right = this.getRight();rn rn /** 垂直判断 **/rn if (isControl_V) rn if (top >= 0) rn top = 0;rn bottom = this.getHeight();rn rnrn if (bottom <= screen_H) rn top = screen_H - this.getHeight();rn bottom = screen_H;rn rn else rn top = this.getTop();rn bottom = this.getBottom();rn rn if (isControl_H || isControl_V)rn this.setPosition(left, top, right, bottom);rnrn current_x = (int) event.getRawX();rn current_y = (int) event.getRawY();rnrn rn /** 处理缩放 **/rn else if (mode == MODE.ZOOM) rnrn afterLenght = getDistance(event);// 获取两点的距离rnrn float gapLenght = afterLenght - beforeLenght;// 变化的长度rnrn if (Math.abs(gapLenght) > 5f) rn scale_temp = afterLenght / beforeLenght;// 求的缩放的比例rnrn this.setScale(scale_temp);rnrn beforeLenght = afterLenght;rn rn rnrn rnrn /** 获取两点的距离 **/rn float getDistance(MotionEvent event) rn float x = event.getX(0) - event.getX(1);rn float y = event.getY(0) - event.getY(1);rnrn return FloatMath.sqrt(x * x + y * y);rn rnrn /** 实现处理拖动 **/rn private void setPosition(int left, int top, int right, int bottom) rn this.layout(left, top, right, bottom);rn rnrn /** 处理缩放 **/rn void setScale(float scale) rn int disX = (int) (this.getWidth() * Math.abs(1 - scale)) / 4;// 获取缩放水平距离rn int disY = (int) (this.getHeight() * Math.abs(1 - scale)) / 4;// 获取缩放垂直距离rnrn // 放大rn if (scale > 1 && this.getWidth() <= MAX_W) rn current_Left = this.getLeft() - disX;rn current_Top = this.getTop() - disY;rn current_Right = this.getRight() + disX;rn current_Bottom = this.getBottom() + disY;rnrn this.setFrame(current_Left, current_Top, current_Right,rn current_Bottom);rn /***rn * 此时因为考虑到对称,所以只做一遍判断就可以了。rn */rn if (current_Top <= 0 && current_Bottom >= screen_H) rn // Log.e("jj", "屏幕高度=" + this.getHeight());rn isControl_V = true;// 开启垂直监控rn else rn isControl_V = false;rn rn if (current_Left <= 0 && current_Right >= screen_W) rn isControl_H = true;// 开启水平监控rn else rn isControl_H = false;rn rnrn rn // 缩小rn else if (scale < 1 && this.getWidth() > MIN_W) rn current_Left = this.getLeft() + disX;rn current_Top = this.getTop() + disY;rn current_Right = this.getRight() - disX;rn current_Bottom = this.getBottom() - disY;rn /***rn * 在这里要进行缩放处理rn */rn // 上边越界rn if (isControl_V && current_Top > 0) rn current_Top = 0;rn current_Bottom = this.getBottom() - 2 * disY;rn if (current_Bottom < screen_H) rn current_Bottom = screen_H;rn isControl_V = false;// 关闭垂直监听rn rn rn // 下边越界rn if (isControl_V && current_Bottom < screen_H) rn current_Bottom = screen_H;rn current_Top = this.getTop() + 2 * disY;rn if (current_Top > 0) rn current_Top = 0;rn isControl_V = false;// 关闭垂直监听rn rn rnrn // 左边越界rn if (isControl_H && current_Left >= 0) rn current_Left = 0;rn current_Right = this.getRight() - 2 * disX;rn if (current_Right <= screen_W) rn current_Right = screen_W;rn isControl_H = false;// 关闭rn rn rn // 右边越界rn if (isControl_H && current_Right <= screen_W) rn current_Right = screen_W;rn current_Left = this.getLeft() + 2 * disX;rn if (current_Left >= 0) rn current_Left = 0;rn isControl_H = false;// 关闭rn rn rnrn if (isControl_H || isControl_V) rn this.setFrame(current_Left, current_Top, current_Right,rn current_Bottom);rn else rn this.setFrame(current_Left, current_Top, current_Right,rn current_Bottom);rn isScaleAnim = true;// 开启缩放动画rn rnrn rnrn rnrn /***rn * 缩放动画处理rn */rn public void doScaleAnim() rn myAsyncTask = new MyAsyncTask(screen_W, screen_H, this.getWidth(),rn this.getHeight());rn myAsyncTask.setLTRB(this.getLeft(), this.getTop(), this.getRight(),rn this.getBottom());rn myAsyncTask.execute();rn isScaleAnim = false;// 关闭动画rn rnrn /***rn * 回缩动画執行rn */rn class MyAsyncTask extends AsyncTask rn private int screen_W, screen_H, current_Width, current_Height;rnrn private int left, top, right, bottom;rnrn private float scale_WH;// 宽高的比例rnrn /** 当前的位置属性 **/rn public void setLTRB(int left, int top, int right, int bottom) rn this.left = left;rn this.top = top;rn this.right = right;rn this.bottom = bottom;rn rnrn private float STEP = 8f;// 步伐rnrn private float step_H, step_V;// 水平步伐,垂直步伐rnrn public MyAsyncTask(int screen_W, int screen_H, int current_Width,rn int current_Height) rn super();rn this.screen_W = screen_W;rn this.screen_H = screen_H;rn this.current_Width = current_Width;rn this.current_Height = current_Height;rn scale_WH = (float) current_Height / current_Width;rn step_H = STEP;rn step_V = scale_WH * STEP;rn rnrn @Overridern protected Void doInBackground(Void... params) rnrn while (current_Width <= screen_W || current_Height <= screen_H) rnrn left -= step_H;rn top -= step_V;rn right += step_H;rn bottom += step_V;rnrn current_Width += 2 * step_H;rn current_Height += 2 * step_V;rnrn left = Math.max(left, start_Left);rn top = Math.max(top, start_Top);rn right = Math.min(right, start_Right);rn bottom = Math.min(bottom, start_Bottom);rn Log.e("jj", "top=" + top + ",bottom=" + bottom + ",left="rn + left + ",right=" + right);rn leftReturn = left;rn topReturn = top;rn rightReturn = right;rn bottomReturn = bottom;rn handler.obtainMessage(0).sendToTarget();rn // onProgressUpdate(new Integer[] left, top, right, bottom );rn try rn Thread.sleep(10);rn catch (InterruptedException e) rn e.printStackTrace();rn rn rnrn scale_temp = 1;rn getParent().requestDisallowInterceptTouchEvent(false);rn return null;rn rnrn红色代码处已经添加了让父类不截获touch消息,为什么viewpager还是能滑动 论坛

没有更多推荐了,返回首页