Android开发笔记(十九)——Android事件处理

Android事件处理:当用户在应用界面上执行各种操作的时候,应用程序需要为用户的动作提供响应,这种响应的过程就是事件处理。

Android组件的事件处理有2种方式:

  1. 基于监听器的事件处理方式:先定义组件,然后为组件设定监听器。
  2. 基于回调的事件处理方式:让每一个组件继承UI类,并重写该类的事件处理方法。当该组件遇到某事件时,即会触发相应的事件处理方法。

一.基于监听的事件处理机制

监听三要素

  • Event Source(事件源):发生事件的控件、监听的目标
  • Event(事件)
  • Event Listener(事件监听器):不同的事件需要不同的监听器

示例1:

  • Event Source(事件源):Button btnTestEvent
  • Event(事件):待定(点击事件是一个比较简单的事件,系统直接会处理,不需要暴露事件对象)
  • Event Listener(事件监听器):new View.OnClickListener()

示例2:

  • Event Source(事件源):Button btnTestEvent
  • Event(事件):MotionEvent event 就是发生的具体事件,
  • Event Listener(事件监听器):new View.OnTouchListener()

实现监听事件的方法

1.通过内部类实现

2.通过匿名内部类实现

这个比较熟悉:通常用于一次性事件处理

3.通过事件源所在类实现

通过当前的Activity(事件源所在类)实现OnClickListener(事件的监听)

4.通过外部类实现(不经常用)

新建一个class,让整个类实现OnClickListener接口

在Activity中写:

5.布局文件中onClick属性(针对点击事件)

这里在之前的Button点击事件中介绍过

在对应的Button添加onClick属性:

这里 show 是自己起的方法的名字
在对应的Activity中添加 show 的实现代码:(注意这里必须是 public void

给同一个事件源添加多个同类型监听器会怎样?

当把上面所有的方法都打开时候,系统会执行最后设置的监听器,其余的不会执行。并且在xml文件中写的onClick属性,认为是最先设置的监听器,只要还设置了别的监听器,就不会执行它。

二.基于回调的事件处理机制

回调机制与监听机制的区别

回调机制:事件源与事件的监听是绑在一起的。
如果说监听机制就是委托式事件处理,事件源和事件处理(监听)是分开的。那么相反的,回调则是两者统一,当用户在触发事件的时候,由控件自己来解决。但是回调也是有它的限制的,它不像监听那样,由我们动态的添加方法(新建一个listener,listener.onCLicker()重写),它必须由我们继承GUI组件类,并重写该类的方法来实现。

基于回调的事件传播

回调也用button响应:

新建一个java类,继承自AppCompatButton:在按钮内部回调onTouchEvent方法

package com.example.myapplication.widget;

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

import androidx.appcompat.widget.AppCompatButton;

public class MyButton extends AppCompatButton {
    public MyButton(Context context) {
        super(context);
    }

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

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

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.d("MyButton","------onTouchEvent-----");
                break;
        }
        return false; //如果这里return true的话,MainActivity就不会响应它的onTouchEvent()事件了
    }
}

xml中的控件:

    <com.example.myapplication.widget.MyButton
        android:id="@+id/btn_my"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="my button"
        android:textAllCaps="false"
        />

然后在相应视图中点击按钮,便是MyButton里面的onTouchEvent()负责响应。

在对应的Activity中设置响应onTouchEvent事件:

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.d("Activity","------onTouchEvent-----");
                break;
        }
        return false;
    }

说明回调机制先从控件本身开始回调,之后还会继续执行Activity中的回调。事件本身是由Button向外传播。

在对应的Activity中设置触摸的监听:

        btnMy.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        Log.d("Listener","------OnTouchListener-----");
                        break;
                }
                return false;
            }
        });

此时,除了在按钮内部回调onTouchEvent方法,Activity中也有onTouchEvent方法,同时还给按钮在Activity中设置了监听器OnTouchListener

运行查看日志:

上面的例子说明了:

  1. 优先级: 监听 > 回调 。
  2. 回调的事件传播: 监听事件 -> 该视图区域最里面的类的回调方法 ->return true 拦截,结束;return false -> 该视图区域上一层类(存在多个视图嵌套子类的情况)的回调方法 -> .... 直到return true或者到最外层Activity
posted @ 2020-07-23 00:13  Ylxxxxx  阅读(411)  评论(0编辑  收藏  举报