您的位置:首页 > 移动开发 > Android开发

Android事件处理

2016-06-17 14:28 387 查看

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);
}
}


 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: