标签:事件拦截 viewgroup嵌套 android手势冲突
转载请标明原文地址:简单灵活解决 Viewgroup嵌套 产生的手势冲突问题
这是接着上一篇Android 下拉刷新上拉加载 多种应用场景 超级大放送(上)的,这里介绍一下怎么 简单灵活解决Viewgroup嵌套产生的手势冲突问题。虽然这里只是以ViewPager为例,但是提供了一种解决此类问题的通用思路。
先来看一下网易新闻客户端的界面效果:
上一篇实现的Demo效果图,手势效果响应和上图一样
关于Viewgroup嵌套产生的手势冲突问题主要分为两类:
这里提供一种 解决以上问题的通用方案:
public class SubView1 extends View { private static String TAG = SubView1.class.getSimpleName(); private GestureDetector mGestureDetector; private Paint paint = new Paint(); public SubView1(Context context) { super(context); } public SubView1(Context context, AttributeSet attrs) { super(context, attrs); // 为mGestureDetector设置监听器 mGestureDetector = new GestureDetector(context, new MTouchDetector()); // 保证能触发相应的事件 setFocusable(true); setClickable(true); setEnabled(true); setLongClickable(true); } protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 指定宽和高 setMeasuredDimension(600, 200); // super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override public void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD)); canvas.drawColor((Color.parseColor("#FFA07A"))); canvas.drawText("SubView1", 100, 100, paint); } @Override public boolean dispatchTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: // L.i(TAG, "dispatchTouchEvent ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: // L.i(TAG, "dispatchTouchEvent ACTION_MOVE"); break; case MotionEvent.ACTION_UP: // L.i(TAG, "dispatchTouchEvent ACTION_UP"); break; default: break; } getParent().requestDisallowInterceptTouchEvent(true); // 先告诉父Viewgroup,不要拦截我我 mGestureDetector.onTouchEvent(event); // 通过GestureDetector将MotionEvent事件交给监听器OnGestureListener return super.dispatchTouchEvent(event); } class MTouchDetector extends SimpleOnGestureListener { // Touch down时触发 public boolean onDown(MotionEvent e) { L.i(TAG, "onDown"); return super.onDown(e); } public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { //tan(60°),手势与垂直方向大于30°,相应子View的onScroll,父Viewgroup的onScroll则不会响应 if (1.732*Math.abs(distanceX) >= Math.abs(distanceY)) { L.i(TAG, "不要拦截我"); getParent().requestDisallowInterceptTouchEvent(true); // 告诉父Viewgroup不要拦截我,事件我自行处理 return true; } else { getParent().requestDisallowInterceptTouchEvent(false);// 告诉父Viewgroup拦截我,响应父Viewgroup的onScroll L.i(TAG, "拦截我"); return false; } } public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { L.i(TAG, "onFling"); return super.onFling(e1, e2, velocityX, velocityY); } // 双击的第二下Touch down时触发 public boolean onDoubleTap(MotionEvent e) { L.i(TAG, "onDoubleTap"); return super.onDoubleTap(e); } public boolean onDoubleTapEvent(MotionEvent e) { L.i(TAG, "onDoubleTapEvent"); return super.onDoubleTapEvent(e); } } }再定义父ViewGroup
public class MLinearLayout extends LinearLayout { private static String TAG = MLinearLayout.class.getSimpleName(); // private static String TAG = SubView1.class.getSimpleName(); private GestureDetector mGestureDetector; @SuppressLint("ClickableViewAccessibility") public MLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); mGestureDetector = new GestureDetector(context, new MTouchDetector()); this.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return mGestureDetector.onTouchEvent(event); } }); setFocusable(true); setClickable(true); setEnabled(true); setLongClickable(true); } @SuppressLint("NewApi") public MLinearLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MLinearLayout(Context context) { super(context); } class MTouchDetector extends SimpleOnGestureListener { public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { L.i(TAG, "onScroll"); return true; } } @Override public boolean onInterceptTouchEvent(MotionEvent event) { // TODO Auto-generated method stub mGestureDetector.onTouchEvent(event); return false; } }<span style="font-size: 11.9999990463257px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 254);"> </span>
/** * @author wen_er * */ public class MyViewPager extends ViewPager { private static String TAG = MyViewPager.class.getSimpleName(); private GestureDetector mGestureDetector; public MyViewPager(Context context) { super(context); mGestureDetector = new GestureDetector(context, new ScrollDetector()); } public MyViewPager(Context context, AttributeSet attrs) { super(context, attrs); // mGestureDetector = new GestureDetector(context, new } class ScrollDetector extends SimpleOnGestureListener { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (Math.abs(distanceX) >= Math.abs(distanceY)) { getParent().requestDisallowInterceptTouchEvent(true);// 告诉父viewGroup不要拦截我 return true; } else { getParent().requestDisallowInterceptTouchEvent(false);// 告诉父viewGroupw拦截我 return false; } } } @Override public boolean dispatchTouchEvent(MotionEvent event) { L.i(TAG, "dispatchTouchEvent"); getParent().requestDisallowInterceptTouchEvent(true); mGestureDetector.onTouchEvent(event); return super.dispatchTouchEvent(event); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:事件拦截 viewgroup嵌套 android手势冲突
原文地址:http://blog.csdn.net/yalinfendou/article/details/47814519