Android事件处理

来源:互联网 发布:心理学本科网络教育 编辑:程序博客网 时间:2024/06/10 21:37

Android有两套事件处理机制:

1.    基于监听的事件处理

2.    基于回调的事件处理

一、  基于监听的事件处理

是一种基于委托式(Delegation)的事件处理方式。

1、        内部类的形式

2、        匿名类的形式

3、        直接绑定到标签

4、        外部类的形式

5、        Activity本身作为事件监听器

其中前三种较为好用,后两种不常用。

1、2大家都很熟悉了。

3举个例子:在Button标签里写一行代码:android:onClick=”clickHandler”,在该布局对应的Activity里定义一个void clickHandler(View source)方法即可。

4使用外部类的话,有两个缺点:

1、        事件监听器通常属于特定的GUI界面,定义成外部类不利于提高程序的内聚性。

2、        外部类形式的事件监听器不能自由访问创建GUI界面的类中的组件,编程不够简洁。此时需要在此外部类的方法里传递Activity、View作为参数才行。

5的话:

1、        Activity的主要职责是完成界面初始化,但此时还有包含事件处理方法,有点混乱。

2、        如果Activity界面类还要实现监听器接口(implements OnClickListener),让人觉得有点怪异。

二、  基于回调的事件处理

对于基于回调的事件处理模型来说,事件源与事件监听器是统一的,或者说事件监听器完全消失了。当用户在GUI组件上激发某个事件是,组件自己特定的方法将会负责处理该事件。举个例子:

类文件:

public class MyButton extends Button{      publicMyButton(Context context , AttributeSet set)      {           super(context, set);      }      @Override      publicboolean onKeyDown(int keyCode, KeyEvent event)      {           super.onKeyDown(keyCode, event);           Log.v("-crazyit.org-","the onKeyDown in MyButton");           //返回true,表明该事件不会向外扩散           returntrue;}


布局文件:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"                   android:orientation="vertical"                   android:layout_width="match_parent"                  android:layout_height="match_parent">      <!--使用自定义View时应使用全限定类名 -->      <org.crazyit.event.MyButton           android:layout_width="match_parent"           android:layout_height="wrap_content"           android:text="单击我"/></LinearLayout>


基于回调的事件传播:

Android系统最先触发的是该按键上绑定的事件监听器,接着触发该组件提供的事件回调方法,然后还会传播到该组件所在的Activity

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


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


三、  响应的系统设置的事件

可使用Configurationcfg = getResourses().getConfiguration();来获取系统的Configuration对象。

如果要使程序自动响应系统设置更改,需要重写Activity的onConfigurationChanged(Configuration neConfig)方法,该方法可用于监听系统设置的更改。

四、Handler消息传递机制

由于Android不允许在子线程中更新界面组件,如果想在子线程中更新界面组件,开发者需要借助于Handler对象来实现。

Handler类的主要作用有两个:

1、        在新启动的线程中发送消息。

2、        在主线程中获取、处理消息。

举个例子:

public class MainActivity extends Activity{      //定义周期性显示的图片的ID      int[]imageIds = new int[]           {                 R.drawable.java,                 R.drawable.javaee,                 R.drawable.ajax,                 R.drawable.android,                 R.drawable.swift           };      intcurrentImageId = 0;      @Override      publicvoid onCreate(Bundle savedInstanceState)      {           super.onCreate(savedInstanceState);           setContentView(R.layout.main);           finalImageView show = (ImageView) findViewById(R.id.show);           finalHandler myHandler = new Handler()           {                 @Override                 publicvoid handleMessage(Message msg)                 {                      //如果该消息是本程序所发送的                      if(msg.what == 0x1233)                      {                            //动态地修改所显示的图片                            show.setImageResource(imageIds[currentImageId++                                       %imageIds.length]);                      }                 }           };           //定义一个计时器,让该计时器周期性地执行指定任务           newTimer().schedule(new TimerTask()           {                 @Override                 publicvoid run()                 {                      //发送空消息                      myHandler.sendEmptyMessage(0x1233);                 }           },0, 1200);      }}


 

 

 

0 0
原创粉丝点击