DrawLayout的全屏滑动(取消长按效果)

关于DrawLayout的一些坑
网上的全屏滑动有两种方法,第一种是自己写手势判断是否滑动

package com.example.apppiaost.util;
import android.app.Activity;
import android.content.Context;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;

public class MyDrawLayout extends DrawerLayout
{
    private float x1, x2, y1, y2;
    public MyDrawLayout(Context context)
    {
        super(context);
    }

    public MyDrawLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public MyDrawLayout(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        if (event.getAction() == MotionEvent.ACTION_DOWN)
        {
            x1 = event.getX();
            y1 = event.getY();
        }
        if (event.getAction() == MotionEvent.ACTION_MOVE)
        {
        }
        if (event.getAction() == MotionEvent.ACTION_UP)
        {
            x2 = event.getX();
            y2 = event.getY();
            if (x1 - x2 > 100)
            {
                this.closeDrawer(Gravity.LEFT);
                return false;
            } else if (x2 - x1 > 100)
            {
                this.openDrawer(Gravity.LEFT);
                return true;
            } else
            {
                this.closeDrawer(Gravity.LEFT);
                return false;
            }
        }
        return super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event)
    {
        if (event.getAction() == MotionEvent.ACTION_DOWN)
        {
            x1 = event.getX();
            y1 = event.getY();
        }
        if (event.getAction() == MotionEvent.ACTION_MOVE)
        {
        }
        if (event.getAction() == MotionEvent.ACTION_UP)
        {
            x2 = event.getX();
            y2 = event.getY();
            if (x1 - x2 > 100)
            {
                this.closeDrawer(Gravity.LEFT);
                return false;
            } else if (x2 - x1 > 100)
            {
                this.openDrawer(Gravity.LEFT);
                return true;
            }
        }
        return super.onInterceptTouchEvent(event);
    }
}

第二种通过反射修改滑动范围

public void setDrawerLeftEdgeSize(Activity activity, DrawerLayout drawerLayout, float displayWidthPercentage)
    {
        if (activity == null || drawerLayout == null)
            return;
        try
        {
              // find ViewDragHelper and set it accessible
            Field leftDraggerField = drawerLayout.getClass().getDeclaredField("mLeftDragger");
            leftDraggerField.setAccessible(true);
            ViewDragHelper leftDragger = (ViewDragHelper) leftDraggerField.get(drawerLayout);
            Field edgeSizeField = leftDragger.getClass().getDeclaredField("mEdgeSize");
            edgeSizeField.setAccessible(true);
            int edgeSize = edgeSizeField.getInt(leftDragger);
            DisplayMetrics dm = new DisplayMetrics();
            activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
            edgeSizeField.setInt(leftDragger, (int) (dm.widthPixels * displayWidthPercentage)); 
        } catch (Exception e)
        {
        }
    }
第一种方法不推荐使用,体验非常不好,特别是有listview这种能上下滑动的控件,
第二种效果就好多了,但是在我看来还有一个bug就是长按时菜单会弹出来,而且会弹到你设定的最大宽度处

DrawLayout的全屏滑动(取消长按效果)_第1张图片
为了解决这个问题试了各种方法都失败了,最终选择了修改源码。
首先,关联v4包的源码(百度上有教程),并找到DrawLayout(eclipse通过ctrl +鼠标左键就能打开)
其次,新建一个java文件,将DrawLayout源码全部粘贴到自己的文件中
最后,修改并使用自己的java文件

/*******修改手势的地方********/
public MyDrawLayout2(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);

        final float density = getResources().getDisplayMetrics().density;
        mMinDrawerMargin = (int) (MIN_DRAWER_MARGIN * density + 0.5f);
        final float minVel = MIN_FLING_VELOCITY * density;

        mLeftCallback = new ViewDragCallback(Gravity.LEFT);
        mRightCallback = new ViewDragCallback(Gravity.RIGHT);

        mLeftDragger = ViewDragHelper.create(this, TOUCH_SLOP_SENSITIVITY, mLeftCallback);
        mLeftDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
        mLeftDragger.setMinVelocity(minVel);
        mLeftCallback.setDragger(mLeftDragger);

        mRightDragger = ViewDragHelper.create(this, TOUCH_SLOP_SENSITIVITY, mRightCallback);
        mRightDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_RIGHT);
        mRightDragger.setMinVelocity(minVel);
        mRightCallback.setDragger(mRightDragger);

        // So that we can catch the back button
        setFocusableInTouchMode(true);
        //修改手势滑动范围(1.0f 代表全屏)
        setDrawerLeftEdgeSize(context,mLeftDragger,1.0f);
        ViewCompat.setAccessibilityDelegate(this, new AccessibilityDelegate());
        ViewGroupCompat.setMotionEventSplittingEnabled(this, false);
    }
    //修改修改手势滑动范围
    public void setDrawerLeftEdgeSize(Context activity,ViewDragHelper mLeftDragger,float displayWidthPercentage)
    {
        Field edgeSizeField;
        try
        {
            edgeSizeField = mLeftDragger.getClass().getDeclaredField("mEdgeSize");
            edgeSizeField.setAccessible(true);
            DisplayMetrics dm = new DisplayMetrics();
            ((Activity)activity).getWindowManager().getDefaultDisplay().getMetrics(dm);
            edgeSizeField.setInt(mLeftDragger, (int) (dm.widthPixels * displayWidthPercentage));
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

/*******取消长按效果的地方1**********/
@Override
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
        final int action = MotionEventCompat.getActionMasked(ev);

        // "|" used deliberately here; both methods should be invoked.
        final boolean interceptForDrag = mLeftDragger.shouldInterceptTouchEvent(ev) | mRightDragger.shouldInterceptTouchEvent(ev);

        boolean interceptForTap = false;

        switch (action)
        {
        case MotionEvent.ACTION_DOWN:
        {
            final float x = ev.getX();
            final float y = ev.getY();
            mInitialMotionX = x;
            mInitialMotionY = y;
            if (mScrimOpacity > 0 && isContentView(mLeftDragger.findTopChildUnder((int) x, (int) y)))
            {
                interceptForTap = true;
            }
            /***多添加的代码closeDrawers(true)**/
            closeDrawers(true);
            mDisallowInterceptRequested = false;
            mChildrenCanceledTouch = false;
            break;
        }
/*******取消长按效果的地方2**********/
@Override
    public boolean onTouchEvent(MotionEvent ev)
    {
        mLeftDragger.processTouchEvent(ev);
        mRightDragger.processTouchEvent(ev);

        final int action = ev.getAction();
        boolean wantTouchEvents = true;

        switch (action & MotionEventCompat.ACTION_MASK)
        {
        case MotionEvent.ACTION_DOWN:
        {
            final float x = ev.getX();
            final float y = ev.getY();
            mInitialMotionX = x;
            mInitialMotionY = y;
            /***多添加的代码closeDrawers(true)**/
            closeDrawers(true);
            mDisallowInterceptRequested = false;
            mChildrenCanceledTouch = false;
            break;
        }

你可能感兴趣的:(DrawLayout的全屏滑动(取消长按效果))