解决事件冲突的三种函数

本文介绍如何在Android中创建自定义View与Layout,并详细解析触摸事件的分发、拦截及处理机制。通过示例代码展示了不同情况下事件的流向与处理逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >




自定义布局
package com.yztc.eventdemo;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

/**
 * 自定义layout布局
 */
public class CustomLayout extends LinearLayout{

    public CustomLayout(Context context) {
        super(context);
    }

    public CustomLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("tag","----------CustomLayout---------onTouchEvent---"+getEventName(event));
        return true;
    }

    /**dispatchTouchEvent 分发事件的方法 不管是view还是viewGroup都具有分发事件的函数
     * 一般情况ViewGroup中将事件分发给子view  View中将事件分发给自己
     * 当事件触发时activity将事件传递到layout layout调用自己的分发方法将事件分发给具体的子控件
     * 子控件也具有分发方法 但是子控件只能分发给自己
     *   接着获取分发的事件调用onTouchEvent()方法处理事件
     *
     *    如果返回true 表示事件会分发给当前的viewdispatchTouchEvent进行处理 并且会停止事件向下传递分发
     *  一般情况都不会修改返回值 改变正常的事件分发流程
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i("tag","----------CustomLayout---------dispatchTouchEvent---"+getEventName(ev));
        return true;
    }

    /**
     * onInterceptTouchEvent事件拦截的方法
     *   事件传递给layout 如果layout不进行拦截 通过拦截的方法 事件就被分发给具体的子控件,
     * 子控件就会执行自己的分发和onTouchEvent()方法处理事件 如果子控件的onTouchEvent()方法并且对
     * 事件处理 事件回传 执行layout中的onTouchEvent() 如果layout中也返回false 事件消失; 如果
     * layoutonTouchEvent()返回true 那么后续的事件也会直接交给layout处理
     *
     * 返回true 表示拦截当前的事件并且交给当前视图的onTouchEvent()处理
     * 返回false 表示不拦截 按照正常的事件传播机制
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.i("tag","----------CustomLayout---------onInterceptTouchEvent---"+getEventName(ev));
        if(ev.getAction()==MotionEvent.ACTION_MOVE){
            return true;
        }
        return false;
    }

    public String getEventName(MotionEvent event){
        String eventName="";
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                eventName="Down 按下";
                break;
            case MotionEvent.ACTION_MOVE:
                eventName="Move 移动";
                break;
            case MotionEvent.ACTION_UP:
                eventName="Up 抬起";
                break;
        }
        return eventName;
    }
}


自定义view视图

package com.yztc.eventdemo;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * 自定义控件
 */
public class CustomView extends View{
    public CustomView(Context context) {
        super(context);
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * onTouchEvent()表示对事件处理的方法
     *   如果事件传播到该类中 表示该类调用onTouchEvent()方法处理该事件
     * 如果该函数返回false  表示不进行事件的处理 将事件进行回传(回传给上层的view或者是viewGroup
     * 由上层的view调用自己的onTouchEvent()方法处理,如果上层的view也未进行事件处理onTouchEvent
     * 返回false那么事件消息 并且接受不到下一次事件 例如:没有处理down事件就不能处理up事件)
     *    如果该方法返回true 表示对当前的事件进行处理  事件只能被处理一次
     *    注意:onTouchEvent()返回false与返回super.onTouchEvent(event) 意思一样
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("tag","----CustomView----onTouchEvent---"+getEventName(event));
        return false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        Log.i("tag","----CustomView----dispatchTouchEvent---"+getEventName(event));
        return super.dispatchTouchEvent(event);
    }

    public String getEventName(MotionEvent event){
        String eventName="";
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                eventName="Down 按下";
                break;
            case MotionEvent.ACTION_MOVE:
                eventName="Move 移动";
                break;
            case MotionEvent.ACTION_UP:
                eventName="Up 抬起";
                break;
        }
        return eventName;
    }
}













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值