Android UI Event Listener

處理UI事件

 

在android上, 有多種方法獲取用戶與應用程序的交互信息. 當考慮UI內部的事件時, 咱們的方法是抓取特定的與用戶交互的View對象產生的事件. android

 

在你用來組成佈局的View對象中,你可能會注意到一些用於處理UI事件的回調函數. 這些方法是被Android框架調用的. 例如,當一個View被按下時, 它的onTouchEvent()方法被調用. 可是,爲了截獲這個信息,你必須擴展這個類並改寫這個方法. 而擴展每一個View對象來處理這樣的事件多是不實際的. 這就是爲何View類還包含一組你能夠更方便定義的嵌套接口. 這些接口被稱爲監聽器, 它們是你用來抓取用戶動做的利器. 算法

 

雖然你可能更加經常使用事件監聽器來監聽用戶動做, 有時候你可能確實但願經過擴展一個View類的方法來作這一點. 可能你但願擴展Button類來作一些巧妙的事情. 在這個狀況下, 你可以使用時間處理器來定義該類的默認的事件行爲. 框架

Event Listeners 事件監聽器

 

一個事件監聽器是View類的一個接口. 該接口包含的方法會在View註冊的事件監聽器被觸發時被Android調用. 函數

 

在事件監聽器中有下列方法: 佈局

 

 

  • onClick() 位於View.OnClickListener中. 在用戶觸摸該對象,或者使用軌跡球等使該對象得到焦點, 並按下"enter"鍵或者按下軌跡球時被調用.
  • onLongClick() 位於 View.OnLongClickListener中. 在用戶按住該元素,或者按住軌跡球時調用.
  • onFocusChange() 位於 View.OnFocusChangeListener中. 該對象得到或失去焦點時調用.
  • onKey() 位於 View.OnKeyListener中. 在該對象得到焦點,而且按下一個鍵時調用.
  • onTouch() View.OnTouchListener. 當用戶在View對象的範圍內進行一個觸摸動做時. 例如按下,放開,或者任何的移動手勢.
  • onCreateContextMenu() View.OnCreateContextMenuListener. 當一個快捷菜單被顯示時(當用戶長按).

這些方法只是它們對應接口的惟一方法. 爲了定義這些方法, 能夠在你的Activity中實現這個接口, 也可使用一個匿名類. 而後, 將實現該接口實例傳給對應的View.set...Listener方法. ui

以OnClickListener爲例: this

// Create an anonymous implementation of OnClickListener
private OnClickListener mCorkyListener = new OnClickListener() {
    
public void onClick(View v) {
      
// do something when the button is clicked
    
}
};

protected void onCreate(Bundle savedValues) {
    
...
    
// Capture our button from layout
    
Button button = (Button)findViewById(R.id.corky);
    
// Register the onClick listener with the implementation above
    button
.setOnClickListener(mCorkyListener);
    
...
}
spa

 

你可能以爲將OnClickListener 實現爲activity的一部分會更加方便. 這能夠避免額外的類. 例如: .net

public class ExampleActivity extends Activity implements OnClickListener {
    
protected void onCreate(Bundle savedValues) {
        
...
        
Button button = (Button)findViewById(R.id.corky);
        button
.setOnClickListener(this);
    
}

    
// Implement the OnClickListener callback
    
public void onClick(View v) {
      
// do something when the button is clicked
    
}
    
...
}
component

 

注意 onClick() 沒有返回值, 但有些事件監聽器必須有一個布爾返回值. 下面是一些緣由:

  • onLongClick() - 返回一個布爾值表示你是否消耗了該event. 也就是,若是你已經處理了該event, 則它應該中止了,就返回true, 而若是你沒有處理它,而是將它留給其它的on-click監聽器, 則返回false.
  • onKey() - 同上.
  • onTouch() - 返回一個布爾值表示你是否消耗了該event. 該event能夠有多個動做. 若是在向下的動做接收時你返回false, 就表示你沒有消耗該event, 而且對後續動做也不感興趣. 也就是說, 後面的手勢動做,以及最後的向上動做都將不會再被通知.

 

鍵事件永遠會被髮送到當前得到焦點的View. 它們是從View層次的頂端開始分派, 而後向下直到合適的目的地. 若是你的View如今擁有焦點, 那麼你能夠從dispatchKeyEvent()方法中看到事件的分派過程. 除了使用veiw以外,你也可使用你的Activity的onKeyDown()和onKeyUp()方法來獲取全部的時間.

 

注意: Android將首先調用事件處理器, 而後調用合適的默認處理器. 所以, 從這些事件監聽器中返回true將使其它監聽器和默認處理器失效. 所以在你返回true時要當心.

Event Handlers 事件處理器

 

若是你從View來建立一個自定義的component,那麼你能夠定義一些默認事件處理器。在 Building Custom Components文檔中,你將看到這些回調函數:

  • onKeyDown(int, KeyEvent) -當一個新的鍵盤時間開始被調用。
  • onKeyUp(int, KeyEvent) -當一個鍵被釋放時調用。
  • onTrackballEvent(MotionEvent) -當軌跡球移動時調用。
  • onTouchEvent(MotionEvent) - 當屏幕發生移動事件時調用。
  • onFocusChanged(boolean, int, Rect) -當一個View丟失焦點時調用。

有一些不屬於View,可是也能直接影響到事件處理的方法:

  • Activity.dispatchTouchEvent(MotionEvent) -能夠在這些事件被分派到窗口以前讓Activity截獲全部的事件。
  • ViewGroup.onInterceptTouchEvent(MotionEvent) -讓ViewGroup在事件分派到子View以前看到這些事件。
  • ViewParent.requestDisallowInterceptTouchEvent(boolean) - 讓父View不要使用onInterceptTouchEvent(MotionEvent)來截獲event.

Touch Mode 觸摸模式

 

但一個用戶使用方向鍵或者軌跡球來在UI上移動時, 須要讓可動做的UI元素得到焦點, 這樣用戶能夠看到什麼東西將得到他們的輸入。若是設備具備觸摸能力,用戶使用觸摸的方式來交互,那麼就沒有必要給一個元素焦點。所以,有一種交互的模式叫作「觸摸模式」。

對於一個可觸摸的設備,一旦用戶觸摸了屏幕,設備就進入觸摸模式。在這之後,只有isFocusableInTouchMode()爲真的View是能夠得到焦點的, 例如文本框。其它的View能夠觸摸,例如按鈕,在觸摸的時候不會得到焦點。它們只是啓動對應的on-click監聽器。在用戶按下方向鍵或者旋轉軌跡球時,設備將退出觸摸模式,並尋找一個view並使他得到焦點。如今,用戶能夠不觸摸屏幕來交互。

觸摸模式狀態在整個系統中被維護。你可使用isInTouchMode()來查詢當前狀態。

Handling Focus 處理焦點

 

android框架會根據用戶輸入來處理焦點的移動。這包含了在View被移除或隱藏或再次出現時改變焦點。View使用isFocusable()和setFocusable()方法來表示和設置它們可否得到焦點。在觸摸模式下,可使用isFocusableInTouchMode()setFocusableInTouchMode().。

 

焦點移動時基於在某方向上最近距離元素的算法。在不多見的情形下,默認的算法可能和開發者的想法不同。在這種狀況下,你能夠提供一個算法,修改如下幾個xml屬性:nextFocusDown, nextFocusLeft, nextFocusRight和 nextFocusUp. 例如:

<LinearLayout
    
android:orientation="vertical"
    ... 
>
  
<Button android:id="@+id/top"
          
android:nextFocusUp="@+id/bottom"
          ... 
/>
  
<Button android:id="@+id/bottom"
          
android:nextFocusDown="@+id/top"
          ... 
/>
</LinearLayout>

 

通常來講,在這個豎直向下的佈局中,從第一個按鈕向上不會走到哪裏。加入上述代碼後,從第一個按鈕向上會使第二個按鈕獲取焦點。

若是你但願將一個View設爲可獲取焦點,那麼加入xml屬性android:focusable="true" 和android:focusableInTouchMode = "true".

 

但願一個View得到焦點時,調用requestFocus().

 

要監聽焦點事件,使用onFocusChange()

http://blog.csdn.net/lmhit/article/details/5576246

相關文章
相關標籤/搜索