zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    cocos2dx进阶学习之CCDirector
    cocos2d-x游戏开发系列教程-超级玛丽03-main函数
    磁盘管理
    磁盘同步操作
    导入、导出一个卷组
    创建VG
    IBM磁盘阵列及文件系统的管理
    AIX查看HBA卡的WWN号
    AIX设备四种状态
    AIX 适配器
  • 原文地址:https://www.cnblogs.com/yangdd/p/13364001.html
Copyright © 2011-2022 走看看