編輯:Android開發實例
在Android平台上,捕獲用戶在界面上的觸發事件有很多種方法,View類就提供這些方法。你在使用各種View視圖來布局界面時,會發現幾個公用的回調方法來捕捉有用的UI觸發事件,當事件在某個View對象上被觸發時,這些方法會被系統框架通過這個對象所調用,例如:當一個View(如一個Button)被點擊,onTouchEvent()方法會在該對象上被調用,所以,為了捕獲和處理事件,必須去繼承某個類,並重載這些方法,以便自己定義具體的處理邏輯,顯然,你更容易明白,為什麼在你使用View類時會嵌套帶有這些回調方法的接口類,這些接口稱為event listeners,它是你去獲取UI交互事件的工具在你繼承View類,以便建立一個自定義組,也許你想繼承Button , 你會更普遍使用事件監聽來捕捉用戶的互動,在種情況下,你可以使用類的event handlers.來預定義事件的處理方法。
View類裡的event listener是一個帶有回調方法的接口,當UI裡的組建是被用戶觸發時,這些方法會被系統框架所調用
onClick()
來自View.OnClickListener 它會被調用當點擊這個Item(在觸摸模式),或者當光標聚集在這個Item上時按下“確認”鍵 ,導航鍵,或者軌跡球。
來自View.OnLongClickListener. 它會被調用當長按這個Item(在觸摸模式),或者當光標聚集在這個Item上時長按 “確認”鍵 ,導航鍵,或者軌跡球。
來自View.OnFocusChangeListener 它會被調用當光標移到或離開這個Item,
來自View.OnKeyListener..它會被調用,當光標移到這個Item,按下和釋放一個按鍵的時候
來自View.OnTouchListener. 它會被調用 ,在這個Item的范圍內點觸的時候
來自View.OnCreateContextMenuListener. 它會被調用, 當上下文菜單被建立時(由於持續的“長按”) 見討論Creating Menus更多的信息。
這些方法和嵌套接口類都是一一對應的,如果確定其中一種方法處理你的互動事件,你需要在Activity中實現這個帶有這個方法的接口,並把它作為匿名類,然後,通過實例的View.set...Listener() 方法來設置監聽器(例如,調用setOnClickListener(),來設置OnClickListener做為監聽器)
下面是為一個按鈕設置監聽器的例子:
// 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); ... }
}
下面這個列子我們會發現用Activity去實現OnClickListener接口,並作為它的一部分,會更方便,而不必去加載額外的類和對象
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 } ... }
這裡注意一下,以上的例子可以看出onClick()是沒有返回值的,但是有些事件處理方法是必須帶返回值,它取決於的具體的事件,有些那麼做的原因,看下面的例子:
onLongClick()
它返回的布爾值表明你已經完成了這個事件的處理,還是應該把它繼續傳下去。返回true表明已經處理完成並且停止了傳遞,如果返回為false表明事件還沒有完成,或者它還需要繼續被傳遞給其他的監聽器
onKey()
它返回的布爾值表明你已經完成了這個事件的處理,還是應該把它繼續傳下去。返回true表明已經處理完成並且停止了傳遞,如果返回為false表明事件還沒有完成,或者它還需要繼續被傳遞給其他的監聽器
onTouch()
它返回的布爾值表明你是否已經完成了這次事件的行動,重要的是後面可能還有很多後續的行動,這樣,如果你返回false,表明在接到下一次的後續行動中,你還沒有完成之前行為也沒有意向去處理隨後的行動,因此,在這個事件的後續行動中將不會再被調用。 如fingure手勢,或最終行動事件
記住:我們所關注的事件肯定是發生在高亮聚集的焦點,它從總視圖(頂級的)被一級一級的向下傳遞,直到我們想要關注的組件,當焦點聚集在這個視圖(或視圖中的子視圖)時 ,你能夠使用dispatchKeyEvent() 作為一種代替方法,來捕獲在視圖上的按鍵事件,你還可以使用onKeyDown()和onKeyUp().來捕獲所有事件內的交互活動
注意:在 Android 框架中會調用event handlers先處理事件,然後會適當的傳遞給二級默認的預定義handlers中;因此 如果返回true,將會停止這個事件的傳遞,View中默認事件處理方法的回調也會被阻止。因此,當你返回true肯定表明你是要終止這個事件的延續。(這個地方有點不懂。。。原文是:Android will call event handlers first and then the appropriate default handlers from the class definition second. As such, returning true from these event listeners will stop the propagation of the event to other event listeners and will also block the callback to the default event handler in the View. So be certain that you want to terminate the event when you return true.)
如果您建立一個繼承於View自定義組件,然後您可以定義一些回調方法用作默認的事件處理程序。該文件中關於Building Custom Components,您會學習一些共用的回調方法用於事件處理,其中包括:
onKeyDown(int, KeyEvent)
- Called when a new key event occurs. onKeyUp(int, KeyEvent)
- Called when a key up event occurs. onTrackballEvent(MotionEvent)
- Called when a trackball motion event occurs. onTouchEvent(MotionEvent)
- Called when a touch screen motion event occurs. onFocusChanged(boolean, int, Rect)
- Called when the view gains or loses focus.
還有其他一些方法,這不屬於View類,但可以直接影響到你處理事件的方式,所以在布局內管理更復雜的事件可以考慮到這些方法:
Activity.dispatchTouchEvent(MotionEvent)
- This allows your Activity
to intercept all touch events before they are dispatched to the window. ViewGroup.onInterceptTouchEvent(MotionEvent)
- This allows a ViewGroup
to watch events as they are dispatched to child Views. ViewParent.requestDisallowInterceptTouchEvent(boolean)
- Call this upon a parent View to indicate that it should not intercept touch events with onInterceptTouchEvent(MotionEvent)
.
當用戶在使用方向鍵或軌跡球浏覽用戶界面時,有必要給於一個焦點在可操作的組件上(如一個Button),使用戶可以看到它將接受輸入命令。如果設備有觸摸功能,那麼,當用戶與界面的交互就不再需要有一個高亮在組件上,或一個焦點在view上,因此,模式的互動名為"觸摸模式"。對於一個觸摸設備,一旦有用戶接觸屏幕時,該設備將進入觸摸模式.在點觸某個View後,只有的它的方法isFocusableInTouchMode()返回為真時,才會有聚集焦點,如文本編輯工具。其他的界面只可以點觸,但不會聚集焦點(高亮),如button 被點觸時就不會聚集焦點,當它被按下時只會調用on-click監聽器的回調方法。
任何時候用戶接觸方向鍵或者滾動軌跡球時,該設備將退出觸摸模式,並聚集焦點,用戶可以恢復與用戶界面的鍵盤交互,而不必在屏幕上。觸摸模式的狀態是由整個系統來維持的(all windows and activities),要查詢目前所處的狀態,你可以調用isInTouchMode()方法來獲得,看看設備目前是否處於觸摸模式。
系統框架將處理日常的焦點移動來響應用戶的輸入,它包刮改變焦點(當界面是被移除,隱藏,或者作為一個新的View變為可用狀態),通過isFocusable()這個方法我們可以知道view是否具有接受焦點的資格,也可以通過setFocusable().來設置view接受焦點的資格,對應在觸摸模式下,你可以調用isFocusableInTouchMode().來獲知是否有焦點來響應點觸,也可以通過setFocusableInTouchMode().來設置是否有焦點來響應點觸的資格.
系統框架控制焦點移動到另一個組件的算法是在某一方向上鄰近的組件,在極個別情況下,默認的算法可能不符合開發者的預想要求,在這種情況下,你可以覆寫下列XML屬性的布局文件: nextFocusDown , nextFocusLeft , nextFocusRight ,和nextFocusUp 設置他們的值來明確
焦點從當前界面移動下個界面的Id。例如:
<LinearLayout android:orientation="vertical" ... > <Button android:id="@+id/top" android:nextFocusUp="@+id/bottom" ... /> <Button android:id="@+id/bottom" android:nextFocusDown="@+id/top" ... /> </LinearLayout>
一般來說,在這個垂直布局,浏覽的焦點會從第一個按鈕開始,不會是從第二個或者其他的,現在topButtont已經通過nextFocusUp (反之亦然)確定了bottom.
通常如果你想宣布用戶界面具有焦點的資格 (如果這個界面在傳統上是沒有的),可以在xml布局裡去加上的android:focusable的屬性,並設置它的值,您也可以宣布在觸摸模式下具有焦點的資格,同樣也只在xml裡添android:focusableInTouchMode.的屬性,並設置它的值. 當用戶請求在某個界面聚集焦點時,會調用requestFocus().這個方法。監聽到焦點活動(獲得焦點或失去焦點都會被通知),會調用onFocusChange(),這個方法,這也是上節所討論的Event Listeners。
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用
這幾天因為項目需求,需要在ImageView上面疊加一層透明圓弧,並且在沿著圓弧的方向顯示相應的文字,效果如下圖所示: 拿到這個需求,首先想到的是自定義
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用