最大范围 外层蓝色区域是继承ViewGroup
中间红色区域,也是继承ViewGroup
最中间黑色区域,是继承View
布局相关的代码:
<!-- 事件分发 --> <view.custom.heimacustomview.event_distribution.AnimalViewGroup xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorPrimary"> <view.custom.heimacustomview.event_distribution.DogViewGroup android:id="@+id/dog_view_group" android:layout_width="180dp" android:layout_height="180dp" android:background="@android:color/holo_red_light"> <view.custom.heimacustomview.event_distribution.DogFootView android:layout_width="60dp" android:layout_height="60dp" /> </view.custom.heimacustomview.event_distribution.DogViewGroup> </view.custom.heimacustomview.event_distribution.AnimalViewGroup>
Activity:
/** * 事件分发相关 */ public static final String DISTRIBUTION_TAG = "distribution_tag"; @Override public boolean dispatchTouchEvent(MotionEvent ev) { boolean result = super.dispatchTouchEvent(ev); Log.d(DISTRIBUTION_TAG, "Activity的dispatchTouchEvent() 返回结果:" + result); return result; } @Override public boolean onTouchEvent(MotionEvent event) { boolean result = super.onTouchEvent(event); Log.d(DISTRIBUTION_TAG, "Activity的onTouchEvent() 返回结果:" + result); return result; }
最外层ViewGroup处理类:
public class AnimalViewGroup extends ViewGroup { private View dogViewGroupView; public AnimalViewGroup(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onFinishInflate() { super.onFinishInflate(); dogViewGroupView = getChildAt(0); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); dogViewGroupView.measure(dogViewGroupView.getLayoutParams().width, dogViewGroupView.getLayoutParams().height); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { Log.i(AnimalViewGroup.class.getSimpleName(), "指定排版>>>>>>>> getMeasuredWidth():" + getMeasuredWidth() + " getMeasuredHeight:" + getMeasuredHeight()); dogViewGroupView.layout((getMeasuredWidth() / 2) - (dogViewGroupView.getWidth() / 2), (getMeasuredHeight() / 2) - (dogViewGroupView.getLayoutParams().height / 2), dogViewGroupView.getLayoutParams().width + ((getMeasuredWidth() / 2) - (dogViewGroupView.getWidth() / 2)), dogViewGroupView.getLayoutParams().height + ((getMeasuredHeight() / 2) - (dogViewGroupView.getLayoutParams().height / 2))); } /** * 事件分发相关 */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { boolean result = super.dispatchTouchEvent(ev); Log.d(DISTRIBUTION_TAG, "AnimalViewGroup的dispatchTouchEvent() 返回值:" + result); return result; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean result = super.onInterceptTouchEvent(ev); Log.d(DISTRIBUTION_TAG, "AnimalViewGroup的onInterceptTouchEvent() 返回值:" + result); return result; } @Override public boolean onTouchEvent(MotionEvent event) { boolean result = super.onTouchEvent(event); Log.d(DISTRIBUTION_TAG, "AnimalViewGroup的onTouchEvent() 返回值:" + result); return result; } }
中间层ViewGroup处理类:
public class DogViewGroup extends ViewGroup { private View dogFootView; public DogViewGroup(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onFinishInflate() { super.onFinishInflate(); // 拿到子类 dogFootView = getChildAt(0); } private int www; private int hhh; @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); dogFootView.measure(dogFootView.getLayoutParams().width, dogFootView.getLayoutParams().height); www = MeasureSpec.getSize(widthMeasureSpec); hhh = MeasureSpec.getSize(heightMeasureSpec); Log.i(DogViewGroup.class.getSimpleName(), "狗:www:" + www + " hhh:" + hhh); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { Log.i(DogViewGroup.class.getSimpleName(), "狗 getMeasuredWidth():" + getMeasuredWidth()); l = (www / 2) - (dogFootView.getLayoutParams().width / 2); t = (hhh / 2) - (dogFootView.getLayoutParams().height / 2); dogFootView.layout(l, t, dogFootView.getLayoutParams().width + l, dogFootView.getLayoutParams().height + t); } /** * 事件分发相关 */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { boolean result = super.dispatchTouchEvent(ev); Log.d(DISTRIBUTION_TAG, "DogViewGroup的dispatchTouchEvent() 返回值:" + result); return result; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean result = super.onInterceptTouchEvent(ev); Log.d(DISTRIBUTION_TAG, "DogViewGroup的onInterceptTouchEvent() 返回值:" + result); return result; } @Override public boolean onTouchEvent(MotionEvent event) { boolean result = super.onTouchEvent(event); Log.d(DISTRIBUTION_TAG, "DogViewGroup的onTouchEvent() 返回值:" + result); return result; } }
最小区域的,View处理类:
public class DogFootView extends View { Paint paint = null; public DogFootView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); paint = new Paint(); paint.setTextSize(30); paint.setColor(Color.WHITE); paint.setAntiAlias(true); } private int www; private int hhh; @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); Log.i(DogFootView.class.getSimpleName(), " getMeasuredWidth:" + getMeasuredWidth() + " getMeasuredHeight:" + getMeasuredHeight()); www = MeasureSpec.getSize(widthMeasureSpec); hhh = MeasureSpec.getSize(heightMeasureSpec); Log.i(DogFootView.class.getSimpleName(), "狗脚 按钮:www:" + www + " hhh:" + hhh); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.BLACK); String str = "我是按钮"; Rect rect = new Rect(); paint.getTextBounds(str, 0, str.length(), rect); canvas.drawText(str, (www / 2) - (rect.width() / 2), (hhh / 2) - (rect.height() / 2) + rect.height(), paint); } /** * 事件分发相关 */ @Override public boolean dispatchTouchEvent(MotionEvent event) { boolean result = super.dispatchTouchEvent(event); Log.d(HeimaTestActivity.DISTRIBUTION_TAG, "DogFootView的dispatchTouchEvent() 返回值:" + result); return result; } @Override public boolean onTouchEvent(MotionEvent event) { boolean result = super.onTouchEvent(event); Log.d(HeimaTestActivity.DISTRIBUTION_TAG, "DogFootView的onTouchEvent() 返回值:" + result); return result; } }
如果在传递过程中,某一环节是ture,会执行自己的onTouchEvent(),事件就会终止
如果在回传过程中,返回ture,事件消费掉,事件也会终止
下面这都是返回false情况下的流程:
AnimalViewGroup的onInterceptTouchEvent() 返回值:false
DogViewGroup的onInterceptTouchEvent() 返回值:false
DogFootView的onTouchEvent() 返回值:false
DogFootView的dispatchTouchEvent() 返回值:false
开始回传
DogViewGroup的onTouchEvent() 返回值:false
DogViewGroup的dispatchTouchEvent() 返回值:false
AnimalViewGroup的onTouchEvent() 返回值:false
AnimalViewGroup的dispatchTouchEvent() 返回值:false
Activity的onTouchEvent() 返回结果:false
Activity的dispatchTouchEvent() 返回结果:false
Activity的onTouchEvent() 返回结果:false
Activity的dispatchTouchEvent() 返回结果:false
事件丢失