Android-自定义控件之事件分发

最大范围 外层蓝色区域是继承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 事件丢失

猜你喜欢

转载自www.cnblogs.com/android-deli/p/9668126.html