Android View 事件体系(4)

View的事件分发机制

    1 点击事件的传递规则

          当一个点击事件(MotionEvent)产生后,系统需要把这个事件传递给一个具体的View,这个传递的过程就是分发过程。

点击事件的分发过程涉及三个很重要的方法:dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent。

  •  dispatchTouchEvent  ( MotionEvent  event ) 

         用来进行事件的分发。如果事件能够传递给当前View,那么此方法一定会被调用,返回结果受当前View的onTouchEvent和下级View的dispatchTouchEvent方法的影响,表示是否消耗当前事件。

  • onInterceptTouchEvent ( MotionEvent  event ) 

         在dispatchTouchEvent方法中调用,用来判断是否拦截某个事件,如果当前View 拦截了某个事件,那么在同一个事件系列当中,此方法不会被再次调用,返回结果表示是否拦截当前事件。   

  • onTouchEvent ( MotionEvent  event ) 

         在dispatchTouchEvent方法中调用,用来处理点击事件,返回结果表示是否消耗当前事件,如果不消耗,则在同一个事件序列中,当前View无法再次接收到事件。  

  • ViewGroup 事件传递的伪代码
 public boolean dispatchTouchEvent(MotionEvent ev) {
       // 默认事件没有被消费
       boolean consume = false;
       if (onInterceptTouchEvent(ev)){
           // 拦截事件,交给自身处理,调用自身onTouchEvent方法
           consume=onTouchEvent(ev);
       }else {
           // 不拦截事件,交给子View处理,子View的dispatchTouchEvent方法会被调用
           consume=child.dispatchTouchEvent(ev);
       }
       return consume;
 }
  • OnTouchListener、onTouchEvent、OnClickListener事件传递优先级

    1 、默认情况

 自定义Button:

@SuppressLint("AppCompatCustomView")
public class viewTestButton extends Button {

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

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

    public viewTestButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("MainActivity", "onTouchEvent:ACTION_DOWN");
                break;

            case MotionEvent.ACTION_MOVE:
                Log.e("MainActivity", "onTouchEvent:ACTION_MOVE");
                break;

            case MotionEvent.ACTION_UP:
                Log.e("MainActivity", "onTouchEvent:ACTION_UP");
                break;
        }
        return super.onTouchEvent(event);
    }
}

 MainActivity 类:

@SuppressLint("ClickableViewAccessibility")
public class MainActivity extends AppCompatActivity{

    private static final String TAG = "MainActivity";
    @BindView(R.id.btn)
    viewTestButton mBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        mBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "onClick:onClick");
            }
        });
        mBtn.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        Log.e(TAG, "onTouch:ACTION_DOWN");
                        break;

                    case MotionEvent.ACTION_MOVE:
                        Log.e(TAG, "onTouch:ACTION_MOVE");
                        break;

                    case MotionEvent.ACTION_UP:
                        Log.e(TAG, "onTouch:ACTION_UP");
                        break;
                }
                return false;
            }
        });
    }
}

默认情况下onTouch 方法返回值是false ,onTouchEvent返回值是super.onTouchEvent(event)

 日志:

com.example.viewtest E/MainActivity: onTouch:ACTION_DOWN
com.example.viewtest E/MainActivity: onTouchEvent:ACTION_DOWN
com.example.viewtest E/MainActivity: onTouch:ACTION_MOVE
com.example.viewtest E/MainActivity: onTouchEvent:ACTION_MOVE
com.example.viewtest E/MainActivity: onTouch:ACTION_UP
com.example.viewtest E/MainActivity: onTouchEvent:ACTION_UP
com.example.viewtest E/MainActivity: onClick:onClick

  2、只修改 onTouch 返回值为true    

com.example.viewtest E/MainActivity: onTouch:ACTION_DOWN
com.example.viewtest E/MainActivity: onTouch:ACTION_MOVE
com.example.viewtest E/MainActivity: onTouch:ACTION_UP

 3、修改 onTouch 返回值为true , 修改onTouchEvent 返回值为true

com.example.viewtest E/MainActivity: onTouch:ACTION_DOWN
com.example.viewtest E/MainActivity: onTouch:ACTION_MOVE
com.example.viewtest E/MainActivity: onTouch:ACTION_UP

3、修改 onTouch 返回值为true , 修改onTouchEvent 返回值为false

com.example.viewtest E/MainActivity: onTouch:ACTION_DOWN
com.example.viewtest E/MainActivity: onTouch:ACTION_MOVE
com.example.viewtest E/MainActivity: onTouch:ACTION_UP

3、只修改onTouchEvent 返回值为true

com.example.viewtest E/MainActivity: onTouch:ACTION_DOWN
com.example.viewtest E/MainActivity: onTouchEvent:ACTION_DOWN
com.example.viewtest E/MainActivity: onTouch:ACTION_MOVE
com.example.viewtest E/MainActivity: onTouchEvent:ACTION_MOVE
com.example.viewtest E/MainActivity: onTouch:ACTION_UP
com.example.viewtest E/MainActivity: onTouchEvent:ACTION_UP

3、只修改onTouchEvent 返回值为false

com.example.viewtest E/MainActivity: onTouch:ACTION_DOWN
com.example.viewtest E/MainActivity: onTouchEvent:ACTION_DOWN

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值