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

Android 的事件处理

2016-09-05 17:24 169 查看

Android 的事件处理

概括:在自学Android的进程中,今天正式步入事件处理。下面将对事件处理的学习过程做一个随学笔记。

一.事件处理概括

android事件处理机制:

基于监听的事件处理

基于回调的事件处理 ->处理通用事件,代码比较简洁

注:基于监听的事件处理比基于回调的事件处理更具优势。

基于监听的事件处理分工明确,事件源和事件监听有两个类分开执行,因此具有更好的可维护性

Android的事件处理机制保证基于监听的事件监听器会被优先触发

**注:**android还允许用户在界面布局文件中为UI组件的android:onClick属性指定事件监听方法。该方法要在Activity中定义,该方法的参数view代表该UI组件。

XML文件中的实现代码

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button"
android:layout_below="@+id/textview"
android:onClick="star"
android:text="被监听按键"/>


Activity中代码

public void star(View souce){
System.out.println("按键被点击了");
}
//方法实现
star(findViewById(R.id.button));


二.基于监听的事件处理

Event source:各个组件

Event :用户操作

Event Listener:监听事件,对事件作出响应

事件监听器的核心就是所包含的方法-事件处理器(Event Handler)

基于监听的事件处理的步骤:

获取事件源:如

Button button = (Button) findViewById(R.id.button)


注册监听器:调用事件源的setXxxListener(XxxListener),XxxListener为事件监听器。如

button.setOnClikListener(new myClickListener
4000
)


事件监听器:为一个类,类似上面的myClickListener类。实现监听器的关键就是实现处理器方法onClick(View v)

class myClickListener implements View.OnClickListener{
public void onClick{
//事件处理方法
}
}


Android为不同的组件提供不同的监听器接口,这些接口以内部类的方式存在。以View为例:

View.OnClickListener:单击事件的事件监听器必须实现的接口

View.OnCreateContextMenuListener:创建上下文菜单事件的事件监听放弃必须实现的接口

View.OnFocusChangeListener:焦点改变事件监听器必须实现的接口

View.OnKeyListener:按键事件的事件监听器必须实现的接口

View.OnLOngClickListener:长单击事件的事件监听器必须实现的接口

View.OnTouchListener:触摸屏事件的事件监听器必须实现的接口

实现事件监听器的几种形式

内部类形式:事件监听器为当前类的内部类

优点:1可以在当前类中复用该监听器

​ 2可以自由访问类中的所有组件

外部类形式:事件监听器定义成一个外部类

优点:时间监听器能够被多个多个GUI所共享

缺点:1时间监听器通常属于特定的GUI界面,定义成外部类不利于提高程序的内聚性

​ 2不能自由访问GUI创建类中组件,编程不够简洁

Activity本身作为一个时间监听器

优点:简洁

缺点:容易造成程序结构混乱

实现实例:

public class xxx extends Activity implements OnClickListener{
.....
button.setOnClickListener(this);
public void onClick(View V){
//事件处理方法
}
}




匿名内部类:使用匿名内部类创建事件监听器对象

实现实例:

button.setOnClickListener(new OnClickListener(){
public void onClick(){
//事件处理方法
}
});


三.基于回调的事件处理

回调机制:当用户在GUI组件上激发某个事件时,组件自己特定的方法将会处理该事件

为了实现回调机制的事件处理,Android为所有的GUI组件提供了一些事件处理的回调方法,其中View类包含如下方法:

boolean onKeyDown(int keyCode , KeyEvent event):当用户在该组件上按下某个按键时触发该方法

boolean onKeyLongPress(int keyCode , KeyEvent event):当用户在该组件上长按某个按键时触发该方法

boolean onKeyup(int keyCode , KeyEvent event):当用户在该组件上松开某个按键时触发该方法

boolean onTouchEvent(MotionEvent event):当用户在该组件上触发触摸屏事件时触发该事件

boolean onTackballEvent(MotionEvent event)当用户在该组件上触发轨迹球屏事件时触发该方法

回调事件处理实例:

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");
System.out.println("按键被点击了");
// 返回false,表明并未完全处理该事件,该事件依然向外扩散
return true;
}
}
XML文件
<org.crazyit.event.MyButton
android:id="@+id/bn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="单击我"
/>


基于回调的事件传播

回调事件处理方法的boolean类型返回值:

true:表明该方法已完全处理该事件,该事件不会向外传播

false:表明该方法未完全处理该事件,该事件会传播出去

四.响应的系统设置的事件

Configuration类:专门用于描述手机设备上的配置信息调用方法:

Configuration cfg = new getResources().getConfiguration();


获得配置的属性有:

public float fontScale 获得当前用户设置的字体的缩放因子

public int keyboard 获取当前设备所关联的键盘类型。返回值:KEYBOARD_NOKEYS、KEYBOARD_QWERTY(普通电脑键盘)、KEYBOARD_12KEY(小键盘)

public int keyboardHidden 返回一boolean值用于标示当前键盘是否可用。系统的硬件或软件键盘可用,返回KEYBOARDHIDDEN_NO,当两者都不可用,返回KEYBOARDHIDDEN_YES

public Locale locale 返回用户当前的Locale

public int mcc 获取移动信号的国家码

public int mnc 获取移动信号的网络码

public int navigation 判断系统上方向导航设备的类型。返回:NAVIGATION_NONAV(无导航)、NAVIGATION_DPAD(DPAD导航)、NAVIGATION_TRACKBALL(轨迹球导航)、NAVIGATION_WHEEL(滚轮导航)等

public int orientation 获取系统屏幕的方向,返回值:ORIENTATION_LANDSCAPE(横向屏幕)、ORIENTATION_PORTAIT(竖向屏幕)、ORIENTATION_SQUARE(方形屏幕)

public int touchscreen 获取系统触摸屏的触摸方式,返回值:TOUCHSCREEN_NOTOUCH(无触摸屏)、TOUCHSCREEN_STYLUS(触摸笔式的触摸屏)、TOUCHSCREEN_FINGER(接收手指的触摸屏)

例如监听屏幕方向的改变:

public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
String screen = newConfig.orientation ==
Configuration.ORIENTATION_LANDSCAPE ? "横向屏幕" : "竖向屏幕";
Toast.makeText(this, "系统的屏幕方向发生改变" + "\n修改后的屏幕方向为:"
+ screen, Toast.LENGTH_LONG).show();
}


在AndroidManifest.xml文件中配置android:configChanges属性

android:configChanges="orientation"


五.Handle消息传递机制

出现的原因:为了解决多个线程并发操作UI组件所引起的线程安全问题,android指定了一条简单的规则:只允许UI线程修改Activity中的UI组件。这样就导致了新启动的线程无法动态的改变改变界面组件的属性值。在android应用开发中,需要让新的线程周期性的改变界面组件的属性值,就需要借助Handler的消息传递机制来实现。

Handler类的主要作用

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

在主线程中获取、传递消息

Handler类包括如下方法用于发送、处理消息

void handleMessage(Message msg) 处理消息的方法,通常被重写

final boolean hasMessages(int what) 检查消息队列中是否包含what属性为指定值的消息

final boolean hasMessages(int what, Object object) 检查消息队列中是否包含what属性为指定值且object属性为指定对象的消息

多个重载的Message obtainMessage() 获取消息

sendEmptyMessage(int what) 发送空消息

final boolean sendEmptyMessageDelayed(int what,long delayMills) 指定多少毫秒之后发送空消息

final boolean sendMessage(Message msg) 立即发送消息

final boolean sendMessageDelayed(Message msg,long delayMills) 定多少毫秒之后发送消息

自动播放动画实例

final Handler myHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
// 如果该消息是本程序所发送的
if (msg.what == 0x1233)
{
// 动态地修改所显示的图片
show.setImageResource(imageIds[currentImageId++
% imageIds.length]);
}
}
};
// 定义一个计时器,让该计时器周期性地执行指定任务
new Timer().schedule(new TimerTask()
{
@Override
public void run()
{
// 发送空消息
myHandler.sendEmptyMessage(0x1233);
}
}, 0, 5000);


和Handler一起工作的组件:

Message:Handler接收和处理的消息对象

Looper:读取MessageQueue中的消息,每个线程只能有一个Looper

MessageQueue:消息队列

Handler:发送消息和处理消息

**注:**Handler发送和处理的消息必须保存在MessageQueue中,而MessageQueue又由Looper负责管理。因此线程中必须有Looper对象

在线程中使用Handler的步骤:

调用Looperde prepare()方法为当前线程创建Looper对象,同时它的构造其中创建出与之匹配的MessageQueue

创建Handle子类的实例,重写handleMessage()方法,该方法负责处理来自其他线程的消息

调用Looper的loop()方法启动Looper

Looper.prepare();
mHandler = new Handler(){
public void handleMesssage(Message msg){

}
};
Looper.loop();


六、异步任务(Async Task)

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