详解Android的两种事件处理机制
作者:petercao 发布时间:2023-10-05 23:37:20
UI编程通常都会伴随事件处理,Android也不例外,它提供了两种方式的事件处理:基于回调的事件处理和基于 * 的事件处理。
对于基于 * 的事件处理而言,主要就是为Android界面组件绑定特定的事件 * ;对于基于回调的事件处理而言,主要做法是重写Android组件特定的回调函数,Android大部分界面组件都提供了事件响应的回调函数,我们主要重写它们就行。
一 基于 * 的事件处理
相比于基于回调的事件处理,这是更具“面向对象”性质的事件处理方式。在 * 模型中,主要涉及三类对象:
1)事件源Event Source:产生事件的来源,通常是各种组件,如按钮,窗口等。
2)事件Event:事件封装了界面组件上发生的特定事件的具体信息,如果 * 需要获取界面组件上所发生事件的相关信息,一般通过事件Event对象来传递。
3)事件 * Event Listener:负责监听事件源发生的事件,并对不同的事件做相应的处理。
基于 * 的事件处理机制是一种委派式Delegation的事件处理方式,事件源将整个事件委托给事件 * ,由 * 对事件进行响应处理。这种处理方式将事件源和事件 * 分离,有利于提供程序的可维护性。
举例:
View类中的OnLongClickListener * 定义如下:(不需要传递事件)
public interface OnLongClickListener {
boolean onLongClick(View v);
}
public interface OnLongClickListener {
boolean onLongClick(View v);
}
View类中的OnLongClickListener * 定义如下:(需要传递事件MotionEvent)
public interface OnTouchListener {
boolean onTouch(View v, MotionEvent event);
}
public interface OnTouchListener {
boolean onTouch(View v, MotionEvent event);
}
二 基于回调的事件处理
相比基于 * 的事件处理模型,基于回调的事件处理模型要简单些,该模型中,事件源和事件 * 是合一的,也就是说没有独立的事件 * 存在。当用户在GUI组件上触发某事件时,由该组件自身特定的函数负责处理该事件。通常通过重写Override组件类的事件处理函数实现事件的处理。
举例:
View类实现了KeyEvent.Callback接口中的一系列回调函数,因此,基于回调的事件处理机制通过自定义View来实现,自定义View时重写这些事件处理方法即可。
public interface Callback {
// 几乎所有基于回调的事件处理函数都会返回一个boolean类型值,该返回值用于
// 标识该处理函数是否能完全处理该事件
// 返回true,表明该函数已完全处理该事件,该事件不会传播出去
// 返回false,表明该函数未完全处理该事件,该事件会传播出去
boolean onKeyDown(int keyCode, KeyEvent event);
boolean onKeyLongPress(int keyCode, KeyEvent event);
boolean onKeyUp(int keyCode, KeyEvent event);
boolean onKeyMultiple(int keyCode, int count, KeyEvent event);
}
public interface Callback {
// 几乎所有基于回调的事件处理函数都会返回一个boolean类型值,该返回值用于
// 标识该处理函数是否能完全处理该事件
// 返回true,表明该函数已完全处理该事件,该事件不会传播出去
// 返回false,表明该函数未完全处理该事件,该事件会传播出去
boolean onKeyDown(int keyCode, KeyEvent event);
boolean onKeyLongPress(int keyCode, KeyEvent event);
boolean onKeyUp(int keyCode, KeyEvent event);
boolean onKeyMultiple(int keyCode, int count, KeyEvent event);
}
三、比对
基于 * 的事件模型符合单一职责原则,事件源和事件 * 分开实现;
Android的事件处理机制保证基于 * 的事件处理会优先于基于回调的事件处理被触发;
某些特定情况下,基于回调的事件处理机制会更好的提高程序的内聚性。
四、基于自定义 * 的事件处理流程
在实际项目开发中,我们经常需要自定义 * 来实现自定义业务流程的处理,而且一般都不是基于GUI界面作为事件源的。这里以常见的app自动更新为例进行说明,在自动更新过程中,会存在两个状态:下载中和下载完成,而我们的程序需要在这两个状态做不同的事情,“下载中”需要在UI界面上实时显示软件包下载的进度,“下载完成”后,取消进度条的显示。这里进行一个模拟,重点在说明自定义 * 的事件处理流程。
4.1)定义事件 * 如下:
public interface DownloadListener{
public void onDownloading(int porgress);//下载过程中的处理函数
public void onDownload();//下载完成的处理函数
}
4.2)实现下载操作的工具类代码如下:
public class DownloadUtils{
private static DownloadUtils instance=null;
private private(){
}
public static synchronized DownloadUtils instance(){
if(instance==null){
instance=new DownloadUtils();
}
returns instance;
}
}
private boolean is Downloading=ture;
private int progress=0;
//实际开发中这个函数需要传人url作为参数,以获取服务器端安装包位置
public void download(DownloadListener listener)throws interruptdeException{
while (isDownloading){
listener.onDownloading(progress);
//下载过程的简单模拟
Thread.sleep(1000);
progress+=10;
if(progress>=100){
isDownloading=false;
}
}
//下载完成
listener.onDownload();
}
}
4.3)最后在main函数中模拟事件源:
public class DownloadUI{
public static void main(sting[] args){
try{
DownloadUtils.instance().download(new MyDownloadListener());
}catch(InterruptedExceptiob e){
e.printStackTrace();
}
}
private static class MyDownloadListener implements DownloadListener{
@Override
public void onDownloading(int progress){
system.out.println("下载进度是:"+progress);
}
@Override
public void onDownloaded(){
system.out.println("下载完成")
}
}
}
运行一下的模拟程序,输入如下所示:


猜你喜欢
- 目录1、Android如何动态更换桌面图标1.1使用场景1.2知识点1.3使用Activity-alias2、巨坑2.1App的覆盖2.2桌
- 目录一、System.out.println(最简单)二、java.util.logging(相对简单)三、log4j(最强大)四、comm
- 新手练手必备~密码账户为:先创建账户类:package cn.Atm;/*** @author 偶my耶*/import java.io.*
- 什么是线程同步? 当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致),所以我们用同步机
- 这篇文章主要介绍了简单了解Spring中BeanFactory与FactoryBean的区别,文中通过示例代码介绍的非常详细,对大家的学习或
- 1. 场景描述本节结合springboot2、springmvc、mybatis、swagger2等,搭建一个完整的增删改查项目,希望通过这
- 前言关于android的volley封装之前写过一篇文章,见链接(https://www.jb51.net/article/155875.h
- 前言Groovy 是一种基于 JVM 的动态语言,与 Java 语言紧密集成,可以很方便地在 Java 项目中使用。Groovy 有着简洁的
- 首先备注一下JAR(Java Archive,Java 归档文件)是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件。为 J2EE
- 1.冒泡排序简介冒泡排序(Bubble Sorting)即:通过对待排序的序列从前往后,依次比较相邻元素的值,若发现逆序则交换位置,使较大的
- Android 中下拉菜单,即如html中的<select>,关键在于调用setDropDownViewResource方法,以
- 最近碰到个需要下载zip压缩包的需求,于是我在网上找了下别人写好的zip工具类。但找了好多篇博客,总是发现有bug。因此就自己来写了个工具类
- 本文实例为大家分享了两种java实现FTP文件上传下载的方式,供大家参考,具体内容如下第一种方式:package com.cloudpowe
- 前提准备:1. 项目中至少需要引入的jar包,注意版本: a) core-renderer.jar&nb
- 1.瞬时流量过高,服务被压垮?2.恶意用户高频光顾,导致服务器宕机?3.消息消费过快,导致数据库压力过大,性能下降甚至崩溃?......在高
- 前言Mybatis作为一个应用广泛的优秀的ORM框架,已经成了JavaWeb世界近乎标配的部分,这个框架具有强大的灵活性,在四大组件(Exe
- 写在前面jenkins作为java的好 * ,经历过单体项目时代->集群项目时代->容器集群分布式时代,使用稳定可靠,cpu友好(
- 先贴正确配置<?xml version="1.0" encoding="UTF-8"?>
- 本文实例为大家分享了springboot+vue实现垃圾分类管理系统的具体代码,供大家参考,具体内容如下一、项目概述1.项目内容本项目利用I
- 1 问题手写一个程序,完成List集合对象的逆序遍历2 方法创建List接口的多态对象向创建好list集合添加元素使用hasPrevious