1: 如果所有的子view都没有消费down事件,事件如何传递
测试代码如下
public class ActivityTouchTestActivity extends AppCompatActivity {
private static final String Tag = ActivityTouchTestActivity.class.getSimpleName();
@Bind(R.id.touch_btn)
Button touchBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity_touch_test);
ButterKnife.bind(this);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
touchBtn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean result=super.dispatchTouchEvent(ev);
Log.v(Tag , "cong " + result);
return result;
}
}
/**
* Created by qing on 16/6/14.
*/
public class BtnTouchView extends Button {
private static final String Tag = BtnTouchView.class.getSimpleName();
public BtnTouchView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean result=super.dispatchTouchEvent(ev);
Log.v(Tag, "cong " + result);
return false;
}
}
log如下:
结论:1 : touch事件传回activity的dispatchTouchEvent,而activity的dispatchTouchEvent并不会将值置为true
2: up事件并未传导到btn
分析:
viewGroup的dispatchTouchEvent中有这么一段代码
if (actionMasked == MotionEvent.ACTION_DOWN
|| mFirstTouchTarget != null) {
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
} else {
// There are no touch targets and this action is not an initial down
// so this view group continues to intercept touches.
intercepted = true;
}
mFirstTouchTarget只有在事件被消费后才会置值,而实际中btn并未消费事件,所以为null,所以viewGroup本身会拦截事件(up事件由viewgroup本身处理)!!!
结果会直行到dispatchTouchEvent中的这块代码:
// Dispatch to touch targets.
if (mFirstTouchTarget == null) {
// No touch targets so treat this as an ordinary view.
handled = dispatchTransformedTouchEvent(ev, canceled, null,
TouchTarget.ALL_POINTER_IDS);