小记DrawerLayout点击事件传递

今天遇到的问题是DrawerLayout在上面,下面的View拿不到点击事件,最后实在没办法,都曲线救国了(只要解决需求,曲线救国也是不错的选择),挽起袖子撸完代码,对曲线救国的效果也比较满意,坐下来没事了就想看看不能解决点击的冲突,就进到DrawerLayout源码里看了一下,发现了这一段

    @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;
                mDisallowInterceptRequested = false;
                mChildrenCanceledTouch = false;
                break;
            }

            case MotionEvent.ACTION_UP: {
                final float x = ev.getX();
                final float y = ev.getY();
                boolean peekingOnly = true;
                final View touchedView = mLeftDragger.findTopChildUnder((int) x, (int) y);
                if (touchedView != null && isContentView(touchedView)) {
                    final float dx = x - mInitialMotionX;
                    final float dy = y - mInitialMotionY;
                    final int slop = mLeftDragger.getTouchSlop();
                    if (dx * dx + dy * dy < slop * slop) {
                        // Taps close a dimmed open drawer but only if it isn't locked open.
                        final View openDrawer = findOpenDrawer();
                        if (openDrawer != null) {
                            peekingOnly = getDrawerLockMode(openDrawer) == LOCK_MODE_LOCKED_OPEN;
                        }
                    }
                }
                closeDrawers(peekingOnly);
                mDisallowInterceptRequested = false;
                break;
            }

            case MotionEvent.ACTION_CANCEL: {
                closeDrawers(true);
                mDisallowInterceptRequested = false;
                mChildrenCanceledTouch = false;
                break;
            }
        }

        return wantTouchEvents;
    }

对,你没看错,他不但拦截了点击事件,还消费了,就说为什么传不下去,既然知道了问题的所在,解决起来就简单多了,我们可以自定义一个DrawerLayout,代码如下,其实很简单就是我们自己来控制DrawerLayout是否相应点击事件,(DrawerLayout为了响应抽屉的打开和收起,所以拦截了点击事件,当初没想起来)

/**
 * Created by Bert on 2017/7/26.
 */

public class MyDrawerLayout extends DrawerLayout {

    private static final String TAG = "MyDrawerLayout";
    private boolean is_click = true;
    
    public MyDrawerLayout(Context context) {
        super(context);
    }

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

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


    /**
     * 控制DrawerLayout是否响应点击事件
     * @param can
     */
    public void setCanClick(boolean can){
        is_click = can;
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if(is_click){
            return super.onTouchEvent(ev);
        }else {
            return false;
        }

    }
}

OK,就这么简单,需要点击事件传递下去的时候setCanClick(false)就Ok了。

总结一下:还是看源码重要!!!!!!!!!

你可能感兴趣的:(小记DrawerLayout点击事件传递)