Android笔记二十四.Android基于回调的事件处理机制

如果说事件监听机制是一种委托式的事件处理,那么回调机制则与之相反,对于基于回调的事件处理模型来说,事件源和事件监听器是统一的,或者说事件监听器完全消失了,当用户在GUI控件上激发某个事件时,控件自己特定的方法将会负责处理该事件。

转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空)

一、View类的常见回调方法

为了使用回调机制来处理GUI控件上所发生的事件,需要为该组件提供对应的事件处理方法,而Java又是一种静态语言,我们无法为每个对象动态地添加方法,因此只能通过继承GUI控件类,并重写该类的事件处理方法来实现。
Android平台中,每个View都有自己处理特定事件的回调方法,我们可以通过重写View中的这些回调方法来实现相应的事件。

二、基于回调的事件处理开发方法

1.自定义控件的一般步骤

(1)定义自己组件的类名,并让该类继承View类或一个现有的View的子类;

(2)重写父类的一些方法,通常需要提供一个构造器,构造器是创建自定义控件的基本方式。当Java代码创建该控件或根据XML布局文件加载并构建界面时都将调用该构造器,根据业务需要重写父类的部分方法。例如onDraw方法,用于实现界面显示,其他方法还有onSizeChanged()、onKeyDown()、onKeyUp()等。

(3)使用自定义的组件,既可通过Java代码来创建,也可以通过XML布局文件进行创建,需要注意的是在XML布局文件中,该组件的标签是完整的包名+类名,而不再仅仅是原来的类名。

2.源码实战

实现:自定义一个按钮,重写其触摸的回调方法。

(1)MyButton.java:自定义组件

package com.example.android_event2;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.Button;
import android.widget.Toast;
public class MyButton extends Button
{
 //构造方法
 public MyButton(Context context, AttributeSet attrs) {
  super(context, attrs);
 }
 //回调方法
 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
   super.onKeyDown(keyCode, event);
   Toast.makeText(getContext(),"您按下了数字:"+keyCode,Toast.LENGTH_SHORT).show();
   return true;	//返回true,表明该事件不会向外扩散
 }
}

(2)layouyt/main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
   <!--方法一:在XML布局文件中创建组件-->
    <com.example.android_event2.MyButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="回调测试" />
</LinearLayout>
(3)MainActivity.java:主Activity
package com.example.android_event2;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //方法二:Java代码中配置自定义组件
    }
}

效果演示:

源码分析:在布局文件中配置自定义的组件---->

<完整的包名.类名  需要设置的相关属性/>

三、事件处理的传播

1. 基于回调方法事件处理的传播

几乎所有基于回调的事件处理方法都有一个boolean类型的返回值,该返回值用于标识该处理方法是否能完全处理该事件。 如果处理事件的回调方法返回true,表明该处理方法已完全处理该事件,该事件不会传播出去;
如果处理事件的回调方法返回false,表明该处理方法并未完全处理该事件,该事件将会继续向外传播。

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

2.源码实战

实现:自定义一个按钮,重写其触摸的回调方法、为其注册触摸事件监听器并重写它所在Activity上的触摸回调方法,观察事件处理顺序。

(1)MainActivity.java

package com.example.android_event2;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.Button;
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //采用监听模式
        Button myButton = (Button)findViewById(R.id.btn);
        myButton.setOnKeyListener(new OnKeyListener(){
   public boolean onKey(View v, int keyCode, KeyEvent event) {
    System.out.println("组件所绑定的事件监听器被触发");
    return false;
   }

        });
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
       super.onKeyDown(keyCode, event);
       System.out.println("该组件所在的Activity的回调方法onKeyDown被调用");
       return false;	//返回true,表明该事件不会向外扩散
    }
}

(2)MyButton.java

package com.example.android_event2;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.Button;
public class MyButton extends Button
{
 //构造方法
 public MyButton(Context context, AttributeSet attrs) {
  super(context, attrs);
 }
 //回调方法
 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
   super.onKeyDown(keyCode, event);
   System.out.println("自定义组件中的回调方法onKeyDown被调用");
   return false;	//返回true,表明该事件不会向外扩散
 }
}

(3)layout/main.xml

package com.example.android_event2;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.Button;
public class MyButton extends Button
{
 //构造方法
 public MyButton(Context context, AttributeSet attrs) {
  super(context, attrs);
 }
 //回调方法
 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
   super.onKeyDown(keyCode, event);
   System.out.println("自定义组件中的回调方法onKeyDown被调用");
   return false;	//返回true,表明该事件不会向外扩散
 }
}

效果演示:

源码分析:

通过实验结果可知,当随意按下一个键后。 最先触发的是该组件所绑定的事件监听器,接着才触发该组件提供的事件回调方法,最后才传播到该组件所在的Activity。如果我们让任何一个事件处理方法返回了true,那么该事件将不会继续向外传播。

四、直接绑定到标签

Android提供了一种直接在界面布局文件中为指定标签绑定事件处理方法的机制。对于很多Android界面控件而言,它们都支持如onClick、onLongClick等属性,这些属性的属性值是一个形如xxx(View
source)方法的方法名。

例如,在布局文件中为按钮添加单击事件的处理方法如下:

<Button

android:layout_width=”wrap_content”

android:layout_heigth=”wrap_content”

android:text=”单击我”

android:onClick=”clickHandler”/>

1.源码实战

(1)MainActivity.java

package com.example.android_event3;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends Activity {
 private EditText text;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        text = (EditText)findViewById(R.id.result);
    }
    //将clickHandler方法直接绑定到标签
    public void clickHandler(View source)
    {
     text.setText("中华人民共和国万岁!");
    }
}

(2)layout/main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
 <Button
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:text="单击我"
     android:onClick="clickHandler"/>
 <EditText
     android:id="@+id/result"
     android:inputType="none"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"/>
</LinearLayout>

效果演示:

时间: 2024-10-12 23:20:33

Android笔记二十四.Android基于回调的事件处理机制的相关文章

Android基础入门教程——3.2 基于回调的事件处理机制

Android基础入门教程--3.2 基于回调的事件处理机制 标签(空格分隔): Android基础入门教程 本节引言 在3.1中我们对Android中的一个事件处理机制--基于监听的事件处理机制进行了学习,简单的说就是 为我们的事件源(组件)添加一个监听器,然后当用户触发了事件后,交给监听器去处理,根据不同的事件 执行不同的操作;那么基于回调的事件处理机制又是什么样的原理呢?好吧,还有一个问题:你知道 什么是方法回调吗?知道吗?相信很多朋友都是了解,但又说不出来吧!好了,带着这些疑问我们 对a

Android笔记二十六.Android异步任务处理(AsyncTask)

转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.引言 我们知道Android的UI线程主要负责处理用户的按键事件.用户触屏事件及屏幕绘图事件等,对于其他的操作尽量不要在UI线程中实现,因为这些操作很有可能会阻塞UI线程,比如一些耗时操作,会导致UI界面停止响应,从而降低了用户的体验.所以,为了避免UI线程失去响应的问题,Android建议将耗时操作放在新线程中完成,但新线程也可能需要动态更新UI组件:比如需要从网上获取一个网页,然后在Te

Android笔记(六十四) android中的动画——补间动画(tweened animation)

补间动画就是只需要定义动画开始和结束的位置,动画中间的变化由系统去补齐. 补间动画由一下四种方式: 1.AplhaAnimation——透明度动画效果 2.ScaleAnimation ——缩放动画效果 3.TranslateAnimation——位移动画效果 4.RotateAnimation——旋转动画效果 1.AplhaAnimation AplhaAnimation的参数: fromAlpha:动画开始时的透明度,0.0表示完全透明 toAlpha:动画结束时的透明度,1.0表示完全不透

Android笔记二十五.Android事件Handler消息传递机制

因为Android平台不同意Activity新启动的线程訪问该Activity里的界面控件.这样就会导致新启动的线程无法动态改变界面控件的属性值.但在实际Android应用开发中,尤其是涉及动画的游戏开发中,须要让新启动的线程周期性地改变界面控件的属性值,这就须要借助Handler的消息传递机制实现. 一.Handler类简单介绍 1.功能 Handler类主要有两个作用 (1)在新启动的线程中发送消息; (2)在主线程中获取消息.处理消息.即当须要界面发生变化的时候.在子线程中调用Handle

Android笔记二十八.Android绘图深度解析

Android绘图深度解析 转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) Android绘图方法主要有两个步骤: (1)实现一个继承于View组件的类,并重写它的onDraw(Canavas canvas)方法; (2)显示定义的View子类,有两种方法:a.使用一个Activity来显示View子类,即 setContentView(new MyView(this, null));b.在Acitviy的布局文件中增加"包名.View子类&

Android进阶(二十四)Android UI---界面开发推荐颜色

Android UI---界面开发推荐颜色   在Android开发过程中,总要给app添加一些背景,个人认为使用纯色调便可以达到优雅的视觉效果. 补充一些常用的颜色值:colors.xml <?xml version="1.0" encoding="utf-8" ?> <resources> <color name="white">#ffffff</color><!--白色 --> &

Android学习笔记二十四之ListView列表视图二

Android学习笔记二十四之ListView列表视图二 前面一篇我们介绍了常用的几种适配器的简单实现和ListView的简单使用,这一篇中,我们介绍一下ListView的优化和一些其它的问题. ListView优化方法一 在ListView中,我们最常用的就是自定义Adapter,在我们自定义Adapter中,需要实现两个比较重要的方法getCount()和getView(),前者是负责计算ListView的总Item数,后者是生成Item,有多少个Item就会调用getView()方法多少次

马哥学习笔记二十四——分布式复制快设备drbd

DRBD: 主从 primary: 可执行读.写操作 secondary: 文件系统不能挂载 DRBD: dual primay, 双主(基于集群文件系统的高可用集群) 磁盘调度器:合并读请求,合并写请求: Procotol:drbd数据同步协议 A: Async, 异步  数据发送到本机tcp/ip协议栈 B:semi sync, 半同步  数据发送到对方tcp/ip协议 C:sync, 同步  数据到达对方存储设备 DRBD Source: DRBD资源 资源名称:可以是除了空白字符外的任意

angular学习笔记(二十四)-$http(2)-设置http请求头

1. angular默认的请求头: 其中,Accept 和 X-Requested-With是$http自带的默认配置 2. 修改默认请求头: (1) 全局修改(整个模块) 使用$httpProvider依赖 var myApp = angular.module('MyApp',[]); myApp.config(function($httpProvider){ console.log($httpProvider.defaults.headers.common) //修改/操作$httpProv