10.1 易於訪問
許多Android使用者有殘疾,需要給他們提供不同的方式來與Android裝置進行互動。
android提供了一個accessibility層,協助使用者更容易的瀏覽android裝置,這又是讓你軟體更強大的一個細節方面,讓我們好好學習吧
10.1.1 允許用一個定向控制器導航
許多android 裝置都具備某種定向控制器,如:
- 一個使用者能在任何方向移動的軌跡球。
- 一個允許使用者在四個方嚮導航的d-pad。
- 一個類似箭頭的按鍵和OK按鈕,相當於點擊一個軌跡球或d-pad 。
通過操作這些控制器,使用者可以不同使用觸控螢幕也能導航到其他介面。關於不使用觸控螢幕而控制導航的方法,最好引入焦點概念。
Android提供了幾個API,讓你控制一個組件是否有焦點,甚至要求一個widget 獲得焦點。這些方法包括:
setFocusable()
isFocusable()
requestFocus()
這是代碼中的方法,如果在xml布局檔案中,我們可以使用 android:focusable
為"true"
10.1.1.1 控制焦點順序
當使用者想要使用定向控制時,焦點從一個View傳遞到另一個View,它由焦點的順序決定。這個焦點運轉的順序是基於一個規則的,這個規則就是它會根據一個特定的方向找最近的鄰居。有時候你可能不想要使用預設的焦點行程順序,你想自己定義。下面就讓我們看看XML中有哪些方法定於焦點順序(下面方法如字面意思就不詳述了)
-
android:nextFocusDown
android:nextFocusLeft
-
android:nextFocusRight
-
android:nextFocusUp
例如,下面有一個Xml布局檔案,TextView上包含一個焦點。當TextView位於EditText的右邊,這樣你按下down arrow 就能吧焦點傳遞到EditText
:
<LinearLayout android:orientation="horizontal"
... >
<EditText android:id="@+id/edit"
android:nextFocusDown=”@+id/text”
... />
<TextView android:id="@+id/text"
android:focusable=”true”
android:text="Hello, I am a focusable TextView"
android:nextFocusUp=”@id/edit”
... />
</LinearLayout>
當然我們還可以在運行時修改焦點順序,例如使用View類的setNextFocusDownId()
和setNextFocusRightId()
.
10.1.1.2 用一個定向控制器點擊
在大多數裝置中,使用定向控制器點擊一個View會發送一個KeyEvent,並且鍵碼為KEYCODE_DPAD_CENTER
到當前獲得焦點的View中。當你在觸控螢幕上觸摸View時確保這個事件是一樣的效
果。所有標準android View會提前適當的處理KEYCODE_DPAD_CENTER
。如果可能的話,建議吧KEYCODE_ENTER
和KEYCODE_DPAD_CENTER
看成一致的。
10.1.2 在你的輸入組件設定一個標籤
許多輸入widgets會有一個提示,讓使用者知道這個是用來輸入什麼的。例如 一個記事本App可能使用帶“+”號的圖片來提示使用者點擊它來添加一個新的記錄。或者一個EditText附近有一個
View,來提示它的用途。當然對於視力有問題的使用者,這種提示是沒什麼用的。關於這種輸入組件,要提供文本提示資訊的話,你可以使用android:contentDescription
屬性。或者使用障礙
語音工具,吧這個屬性的描述朗讀給使用者很多View中都有這個android:contentDescription
到時候用的時候在查即可,下面是一個ImageButton使用這個屬性的例子。
<ImageButton
android:id=”@+id/add_entry_button”
android:src=”@drawable/plus”
android:contentDescription=”Add note”/>
10.1.3 從自訂群組件發送Accessibility Events
如果您的應用程式,您需要建立一個自訂的視圖組件,你可能需要做一些額外的工作,以確保您的View是可訪問。具體來說,你應該確保你的View實現AccessibilityEventSource
介面並在
適當的時間發送AccessibilityEvent,因為每個AccessibilityEvent
包含關於View狀態的重要訊息。
在使用者介面上,當有重要的事件發生就發送一個事件。目前有五種訪問事件,View應該發送此事件到系統用來與使用者互動:
-
TYPE_VIEW_CLICKED
-
表明使用者點擊一個View(例如,使用者選擇一個按鈕)
-
TYPE_VIEW_LONG_CLICKED
-
表明使用者正在對一個View長按
-
TYPE_VIEW_SELECTED
-
表明使用者在view中選擇一個item。通常適用於一個
AdapterView
中
-
TYPE_VIEW_FOCUSED
-
表明使用者移動焦點到view
-
TYPE_VIEW_TEXT_CHANGED
-
表明View的文本或內容被改變了
基本的View類實現了 AccessibilityEventSource
並在適當的時候發送這些事件。你自訂的View應該繼承Android中的View類。
根據我們自訂View的特性,我們可以使用sendAccessibilityEvent()
來發送特定的事件
例如,假設你自訂一個滑塊允許使用者按向左或向右選擇一個數值。這時每當滑塊值的變化,就發出一個TYPE_VIEW_TEXT_CHANGED類型的事件:
@Override
public boolean onKeyUp (int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
mCurrentValue--;
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
return true;
}
...
}
每個AccessibilityEvent有一組所需的屬性描述目前狀態的View。這些屬性包括像View的類名,文本和選中狀態。每個事件類型所需要的具體屬性描述在AccessibilityEvent檔案。
View中還有一個dispatchPopulateAccessibilityEvent()方法,當AccessibilityEvent被發送前用來改變AccessibilityEvent對象。
以上面的滑塊為例,View應該增加滑塊的當前值的事件文本:
@Override
public boolean dispatchPopulateAccessibilityEvent(final AccessibilityEvent event) {
super.dispatchPopulateAccessibilityEvent(event);
if (!isShown()) {
return false;
}
CharSequence text = String.valueOf(mCurrentValue);
if (text.length() > AccessibilityEvent.MAX_TEXT_LENGTH) {
text = text.subSequence(0, AccessiblityEvent.MAX_TEXT_LENGTH);
}
event.getText().add(text);
return true;
}