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.源代码实战
实现:自己定义一个button。重写其触摸的回调方法。
(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.源代码实战
实现:自己定义一个button,重写其触摸的回调方法、为其注冊触摸事件监听器并重写它所在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加入单击事件的处理方法例如以下:
<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>
效果演示:


posted @ 2017-07-28 11:59  zsychanpin  阅读(2432)  评论(0编辑  收藏  举报