您好,登錄后才能下訂單哦!
Android事件處理機(jī)制有兩種:
基于監(jiān)聽的事件處理
基于回調(diào)的事件處理。
基于監(jiān)聽的想必學(xué)過java或者接觸過Android的都了解,最近看了一下有關(guān)回調(diào)方面的書,今天主要是想說一下基于回調(diào)的事件處理機(jī)制。多為我自己的理解總結(jié)和借鑒別人的一些東西,有錯誤或者不理解的地方可以在評論處指出來,謝謝~
基于回調(diào)事件處理的做法:
重寫Android組件特定的回調(diào)方法,或者重寫activity的回調(diào)方法,Android絕大部分界面組件都提供有事件響應(yīng)的回調(diào)方法,開發(fā)者只要重寫即可。一般的,基于回調(diào)的事件處理可用于具有通用型事件,它的代碼簡潔。
一、回調(diào)機(jī)制和監(jiān)聽機(jī)制
對于基于回調(diào)事件處理模型來說事件源與事件監(jiān)聽器是統(tǒng)一的,就是說當(dāng)用戶在GUI組件上激發(fā)某個事件時(shí),組件自己特定的方法將負(fù)責(zé)處理該事件。為了使用回調(diào)機(jī)制類處理GUI組件上發(fā)生的事件,我們需要為該組件提供對應(yīng)的事件處理方式,但是java是靜態(tài)語言,我們無法為某個對象動態(tài)添加方法,只能繼承GUI組件類,然后重寫該類的事件處理方法來實(shí)現(xiàn)。
為實(shí)現(xiàn)回調(diào)機(jī)制的事件處理,Android為所有GUI組件都提供了一些事件處理的回調(diào)方法。以View為例,該類包含如下方法:
boolean onKeyDown(int keyCode,KeyEvent event):當(dāng)用戶在該組件上按下某個按鍵時(shí)觸發(fā)該方法。
boolean onKeyLongPress(int keyCode,KeyEvent event):當(dāng)用戶在該組件上長按某個按鍵時(shí)觸發(fā)該方法。
boolean onKeyShortcut(int keyCode,KeyEvent event):當(dāng)一個鍵盤快捷鍵事件發(fā)生時(shí)觸發(fā)該方法。
boolean onKeyup(int keyCode,KeyEvent event):當(dāng)用戶在該組件上松開某個按鍵時(shí)觸發(fā)該方法。
boolean onTouchEvent(MotionEvent event):當(dāng)用戶在該組件上觸發(fā)觸摸屏?xí)r觸發(fā)該方法。
boolean onTrackballEvent(MotionEvent event):當(dāng)用戶在該組件上軌跡球屏事件時(shí)觸發(fā)該方法。
基于回調(diào)的事件處理機(jī)制可通過自定義View來實(shí)現(xiàn),自定義View時(shí)重寫該View的事件處理方法即可。
如下例子
自定義Button類:
package com.example.testnoew;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Button;
public class MyButton extends Button{
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
public boolean onKeyDown(int keyCode,KeyEvent event){
super.onKeyDown(keyCode, event);
Log.v("MYPROJECT", "onKeyDown in MYBUTTON");
//返回TRUE 表明該事件不會向外擴(kuò)散;
return true;
}
}
xml文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<!-- 自定義View用時(shí)使用全限定類名 -->
<com.example.testnoew.MyButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me"
/>
</RelativeLayout>
然后再activity中調(diào)用這個xml文件就好了,接下來運(yùn)行起來看你的Logcat(不會過濾logcat就自己網(wǎng)上去看),因?yàn)橹貙懙腗yButton中的onKeyDown消費(fèi)了點(diǎn)擊事件,因此不會傳播出去,也就是說按鈕會自己處理事件(當(dāng)然實(shí)際開發(fā)中這個部分就是我們要自己寫東西)。
二、基于回調(diào)的事件傳播(事件分發(fā)機(jī)制)
幾乎所有的基于回調(diào)的事件處理方法都有一個Boolean類型的返回值,該返回值用于標(biāo)識該處理方法是否能完全處理該事件。
如果處理事件的回調(diào)方法返回true,表明該處理方法已完全處理該事件(已消費(fèi)掉)。該事件不會傳播出去。
如果處理事件的回調(diào)方法返回false,表明該處理方法未完全處理該事件,該事件會傳播出去。
對于基于回調(diào)的事件傳播而言,某組件所發(fā)生的事情不僅能夠激發(fā)該組件的回調(diào)方法,也會觸發(fā)該組件所在的activity的回調(diào)方法(只要能夠傳播到該activity,也就是說某組件不把這個事件消費(fèi)掉)。
主activity ,重寫onKeyDown方法,該方法會在某個按鍵被按下時(shí)被回調(diào)
public class MainActivity extends Activity {
private Button testButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
testButton = (Button)findViewById(R.id.btn_test);
testButton.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View Source,int kyeCode,KeyEvent event)
{
//只處理按下的事件
if(event.getAction() == KeyEvent.ACTION_DOWN){
Log.i("MYPROJECT", "in Activity Button Listener!");
}
//表明該事件會向外繼續(xù)傳播
return false;
}
});
}
/*
* (non-Javadoc)
* @see android.app.Activity#onKeyDown(int, android.view.KeyEvent)
* onKeyDown方法可監(jiān)聽整個activity包含的所有組件的按鍵被按下事件
*
*/
public boolean onKeyDown(int keyCode, KeyEvent event){
super.onKeyDown(keyCode, event);
Log.i("MYPROJECT", "in Activity");
return false;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
自定義的MyButton類
package com.example.testnoew;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Button;
public class MyButton extends Button{
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
public boolean onKeyDown(int keyCode,KeyEvent event){
super.onKeyDown(keyCode, event);
Log.v("MYPROJECT", "onKeyDown in MYBUTTON");
//返回false 表明該事件沒有被空間本身自己處理,會向外傳播;
return false;
}
}
xml文件基本沒變,只是給自定義的Button添加了一個id;
通過我們看自己的logcat可以發(fā)現(xiàn)當(dāng)該組件上某個按鍵被按下的事件發(fā)生時(shí),Android系統(tǒng)會最先觸發(fā)該按鍵綁定的事件監(jiān)聽器,然后觸發(fā)該組件提供的事件回調(diào)方法,然后會傳播到該組件所在的activity中。當(dāng)然如果我在回調(diào)或者事件監(jiān)聽中返回true,那么意味著該事件不會繼續(xù)向外傳播 。
三、重寫onTouchEvent方法響應(yīng)觸摸屏事件
Android事件處理機(jī)制保證基于監(jiān)聽的事件監(jiān)聽器會被有限觸發(fā)。
基于監(jiān)聽的事件模式分工明確,事件源,事件監(jiān)聽由兩個類分開,實(shí)現(xiàn),因此可維護(hù)性好點(diǎn)。
基于回調(diào)的事件處理機(jī)制一定程度上具有高內(nèi)聚的特性。
具體的實(shí)例和上面的大同小異,比如, 我自定義控件,然后再自定義控件內(nèi)部重寫onTouchEvent事件,在這個事件中處理比如位置、大小等變化,然后返回 true,這樣所在的activity就不會再處理它。
然后再xml中直接調(diào)用這個控件就好了。
本人也是剛工作不到半年,然后這些東西也是看了寫書才有所理解,在這里拋磚引玉,有不對的地方歡迎來噴。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。