美文网首页
处理View滑动冲突

处理View滑动冲突

作者: 加油小李 | 来源:发表于2022-11-15 00:07 被阅读0次

    内部拦截法和外部拦截法

    外部拦截法

    ViewGroup可以拦截掉Move事件但是不能拦截掉Down事件,因为View
    还要相应Down事件
    在自定义ViewGroup里面重写 onInterceptTouchEvent(MotionEvent ev)方法
    并对Move的移动进行拦截。
    import android.content.Context;
    import android.support.v4.widget.SwipeRefreshLayout;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;

    import java.lang.reflect.Field;

    public class MySwipeRefreshLayout extends SwipeRefreshLayout {
    private static final String TAG = "MySwipeRefreshLayout";

    public MySwipeRefreshLayout(Context context) {
        super(context);
    }
    
    public MySwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    private float startX;
    private float startY;
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = ev.getX();
                startY = ev.getY();
               return false;
            case MotionEvent.ACTION_MOVE:
                float delX = Math.abs(ev.getX() - startX);
                float delY = Math.abs(ev.getY() - startY);
                //因为在move事件的时候,虽然子View设置了,getParent().requestDisallowInterceptTouchEvent(false);
                //但是往下滑动的时候我们发现在SwipeRefreshLayout的源码中报了以下错误
                //Got ACTION_MOVE event but don't have an active pointer id.
                //报这个错误的原因是因为 if (this.mActivePointerId == -1) 这个条件成立
                //所以我们需要想办法把这个属性改掉,由于SwipeRefreshLayout没有直接的API修改
                //因此我想到了反射把mActivePointerId属性改成0
                if ((delY - delX) > 0) {
                    Class clazz = getClass().getSuperclass();
    
                    Field field = null;
                    try {
                        field = clazz.getDeclaredField("mActivePointerId");
                        field.setAccessible(true);
                        field.setInt(this, 0);
                        Log.e(TAG, "onInterceptTouchEvent: 反射成功");
                    } catch (Exception e) {
                        Log.e(TAG, "onInterceptTouchEvent: 反射失败" + e.getMessage());
                        e.printStackTrace();
                    }
                }
    
                break;
    
        }
        return super.onInterceptTouchEvent(ev);
    
    }
    

    }

    内部拦截法

    import android.content.Context;
    import android.support.v4.view.ViewCompat;
    import android.support.v4.view.ViewPager;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;

    public class MyViewPager extends ViewPager {

    private static final String TAG = "MyViewPager";
    
    
    public MyViewPager(Context context) {
        super(context);
    }
    
    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    private float startX;
    private float startY;
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "子View: ACTION_DOWN");
                getParent(). requestDisallowInterceptTouchEvent(true);
                startX = ev.getX();
                startY = ev.getY();
                break;
    
            case MotionEvent.ACTION_MOVE:
                float delX = Math.abs(ev.getX() - startX);
                float delY = Math.abs(ev.getY() - startY);
                if (delX < delY) {
                    Log.e(TAG, "子View: 取消禁用拦截");
                    getParent().requestDisallowInterceptTouchEvent(false);
                    return false;
                }
    
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "子View: ACTION_UP");
                break;
            case MotionEvent.ACTION_CANCEL:
                Log.e(TAG, "子View: ACTION_CANCEL");
                break;
        }
        return super.dispatchTouchEvent(ev);
    }
    

    }

    相关文章

      网友评论

          本文标题:处理View滑动冲突

          本文链接:https://www.haomeiwen.com/subject/qayntdtx.html