• 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 事件丢失
  • 相关阅读:
    简单1694. 重新格式化电话号码
    非暴力破解788. 旋转数字
    竞赛01. 化学反应
    链表2. 两数相加
    日常777. 在LR字符串中交换相邻字符
    竞赛02. 销售出色区间
    竞赛03. 重复的彩灯树
    力扣做题08. 零矩阵
    python3 安装 impyla
    git clone 指定分支
  • 原文地址:https://www.cnblogs.com/android-deli/p/9668126.html
Copyright © 2020-2023  润新知