小记DrawerLayout点击事件传递
2017-07-26 本文已影响59人
BertSir
今天遇到的问题是DrawerLayout在上面,下面的View拿不到点击事件,最后实在没办法,都曲线救国了(只要解决需求,曲线救国也是不错的选择),挽起袖子撸完代码,对曲线救国的效果也比较满意,坐下来没事了就想看看不能解决点击的冲突,就进到DrawerLayout源码里看了一下,发现了这一段
<pre>
@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;
}
</pre>
对,你没看错,他不但拦截了点击事件,还消费了,就说为什么传不下去,既然知道了问题的所在,解决起来就简单多了,我们可以自定义一个DrawerLayout,代码如下,其实很简单就是我们自己来控制DrawerLayout是否相应点击事件,(DrawerLayout为了响应抽屉的打开和收起,所以拦截了点击事件,当初没想起来)
<pre>
/**
- 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;
}
}
}
</pre>
OK,就这么简单,需要点击事件传递下去的时候setCanClick(false)就Ok了。
总结一下:还是看源码重要!!!!!!!!!