欢迎使用CSDN-markdown编辑器

学习资料 : 疯狂Android讲义_Android事件处理

学习笔记:——————————————————————————————————————

Android事件处理概念 :
当用户在程序应用界面上执行各种操作时,应用程序必须为用户提供响应动作,这种响应动作就需要通过事件处理来完成

Android提供了两种方式的事件处理: 基于回调的事件处理 和 基于监听的事件处理

一 : 基于监听的处理

事件监听主要涉及以下三类对象
Event Source [事件源] 事件的发生场所 , 通常就是各个组件,例如按钮, 窗口 , 菜单等
Event [事件] 事件封装了界面组件上发生的特定的事件, 比如用户在界面上按钮 , 移动,抬起 等等 , 一般通过Event对象来获得用户所做的事件
Event Listener[事件监听器] 负责监听事件源所发生的事件 , 并对各事件作出相应的响应

当用户按下按钮或者单击某个菜单选项的时候, 这些动作就会激发一个相应的事件 , 该事件就会触发事件源身上的事件监听器 , 事件监听器就会调用事件处理器(事件监听器里的实例方法)来作出相应的处理

事件处理流程事例图

点击事件:

接下来的小案例 ; 按钮就是事件源,我们需要自己手动为事件源绑定事件监听器—事件监听器必须由开发者来实现
View.OnClickListener 实现了该接口的子类,必须实现未实现的方法 , 该类将会作为事件监听器使用,当按钮被点击时,他的方法,就是事件处理器,
我们可以在该方法中进行相应的操作
我们一般都是直接使用匿名内部类作为事件监听器类来使用

package org.crazyit.event;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
// 实现事件监听器接口
public class ActivityListener extends Activity
    implements OnClickListener
{
    EditText show;
    Button bn;
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        show = (EditText) findViewById(R.id.show);
        bn = (Button) findViewById(R.id.bn);
        // 直接使用Activity作为事件监听器
        bn.setOnClickListener(this);
    }
    // 实现事件处理方法
    @Override
    public void onClick(View v)
    {
        show.setText("bn按钮被单击了!");
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_horizontal"
    >
<EditText 
    android:id="@+id/show"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:editable="false"
    />
<Button 
    android:id="@+id/bn"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="单击我"
    />
</LinearLayout>

基于监听的事件处理规则
(1)事件源: button,任何组件都可以作为事件源
(2)事件监听器: OnXXXListener , 该类必须由我们手动实现, 最关键的一步就是使用该类中的方法
(3)注册监听器: 事件源 . setOnXXXListener

事件监听处理中,主要涉及三个成员 , 事件源, 事件, 事件监听器
事件源就是控件,
事件: 具体是什么事件,是由系统产生的, 我们不用考虑 ;
实现事件监听器 , 是整个事件处理的核心

在上面的小案例中,我们并为发现事件的踪迹, 这是因为android对事件监听模型做了进一步的简化 , 如果事件源触发的事件足够简单,就无需封装事件对象, 直接将该事件传递到事件监听器中了

二 : 基于回调的事件处理

为了实现回调机制的事件处理, Android为所有的View组件都提供了一些事件处理的回调方法 , 以View为例,

小案例 :
基于回调事件处理机制通过自定义View实现 , 自定义View直接重写该View的事件处理方法即可 , 这里我们自定义Button为例

package org.crazyit.event;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Button;
public class MyButton extends Button
{
    public MyButton(Context context, AttributeSet set)
    {
        super(context, set);
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        super.onKeyDown(keyCode, event);
        Log.v("-crazyit.org-", "the onKeyDown in MyButton");
        // 返回true,表明该事件不会向外扩散
        return true;
    }
}

直接在xml中使用该控件

onKeyDown这个方法,会负责处理该按钮上的键盘事件
我们将程序运行到模拟器上,使按钮获取焦点, 按下电脑的键盘任意键, Log就会打印日志

总结 : 对于监听事件处理来说 , 事件处理和事件源是分开的,当发生特定事件之后,事件将会传递给事件监听类中的事件处理方法
对于回调事件处理来说 , 事件处理和事件源是统一的,当发生特定的事件之后,该事件由事件源本身处理

基于回调的事件传播 :

几乎所有的回调处理事件都有一个boolean类型返回值, 该返回值用于标示该处理方法是否完全处理该事件
返回true: 完全处理该事件, 事件不会再进行传播
返回false: 该处理方法并为完全处理该事件 , 事件会继续传播出去

对于基于回调的事件传播而言, 某组件身上所发生的事件 , 不仅激发该组件身上的回调方法, 也会触发该组件所在的Activity的回调方法 –>前提是事件能传递到该Activity

小案例:
重写Button的onKeyDown方法
重写该控件所在Activity的onKeyDown方法

程序不阻止事件传播, 我们将看到事件将传递到Activity中

public class MyButton extends Button
{
    public MyButton(Context context , AttributeSet set)
    {
        super(context , set);
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        super.onKeyDown(keyCode , event);
        Log.v("-MyButton-" , "the onKeyDown in MyButton");
        // 返回false,表明并未完全处理该事件,该事件依然向外扩散
        return false;
    }
}

public class Propagation extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button bn = (Button) findViewById(R.id.bn);
        // 为bn绑定事件监听器
        bn.setOnKeyListener(new OnKeyListener()
        {
            @Override
            public boolean onKey(View source
                    , int keyCode, KeyEvent event)
            {
                // 只处理按下键的事件
                if (event.getAction() == KeyEvent.ACTION_DOWN)
                {
                    Log.v("-Listener-", "the onKeyDown in Listener");
                }
                // 返回false,表明该事件会向外传播
                return false; // (1)
            }
        });
    }
    // 重写onKeyDown方法,该方法可监听它所包含的所有组件的按键被按下事件
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        super.onKeyDown(keyCode , event);
        Log.v("-Activity-" , "the onKeyDown in Activity");
        //返回false,表明并未完全处理该事件,该事件依然向外扩散
        return false;
    }
}

接下来我们通过Log看下事件传递的顺序

当该组件上发生某个按键被按下的事件时,
[1]Android系统最先触发的是该控件身上绑定的事件监听器 ,
[2]前提第一步返回false, 接下来触发该组件中提供的事件回调方法
[3]前提第二步返回false,最终事件将会传递到Activity中的回调方法

反例 :
如果我们将监听器中的回调方法返回值返回true , 证明该方法完全处理该事件 , 事件将不会再进行传递
Log打印:


重写onTouchEvent方法响应触摸屏事件

基于监听事件处理方式 更加强大, 事件源, 事件监听由两个类分开实现 , 因此具有更好的可维护性
android的事件处理机制保证基于监听的事件监听器会被优先触发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值