1. 程式人生 > >11. 自定義鍵盤動作

11. 自定義鍵盤動作

11.1 問題

要自定義軟鍵盤上Enter鍵的外觀,或者改變使用者按這個鍵所觸發的動作,或者兩者都要實現。

11.2 解決方案

(API Level 3)
自定義鍵盤輸入資料小部件的輸入方法(Input Method,IME)選項。

11.3 實現機制

1. 自定義Enter鍵

軟鍵盤出現在螢幕上時,Enter鍵上的文字通常顯示的是根據當前聚焦的控制元件在檢視中的順序所執行的動作。在沒有特別指定時。如果檢視中還有其他可聚焦的控制元件,這個按鍵會顯示next動作;如果當前聚焦的物件已經是最後一個可聚焦物件,則會顯示done動作。對於多行欄位,該動作為換行。對於每個輸入檢視,通過檢視的XML檔案中的android:imeOptions可以自定義這個值。可用於自定義Enter鍵的值如下所示:

  • actionUnspecified :預設值,根據裝置的情況顯示動作。
    動作事件是IME_NULL。
  • actionGo : 在Enter鍵上顯示Go。
    動作事件是IME_ACTION_GO。
  • ActionSearch :在Enter鍵上顯示搜尋圖示。
    動作事件是IME_ACTION_SEARCH。
  • actionSend : 在Enter鍵上顯示Send。
    動作事件是IME_ACTION_SEND。
  • actionNext : 在Enter鍵上顯示Next。
    動作事件是IME_ACTION_NEXT。
  • actionDone :在Enter鍵上顯示Done。
    動作事件是IME_ACTION_DONE。
    下面看一個有兩個可編輯文字框的佈局,如以下程式碼清單所示。第一個文字框在Enter鍵上顯示搜尋放大鏡圖示,第二個則顯示Go。
    res/layout/main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">
  <EditText
    android:id="@+id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:singleLine="true"
    android:imeOptions="actionSearch"/>
  <EditText
    android:id="@+id/text2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:singleLine="true"
    android:imeOptions="actionGo"/>
</LinearLayout>

最終顯示的鍵盤可能會因為生產商自定義的使用者介面工具包而有些許差異,Google原生使用者介面的效果如圖所示。
Enter鍵上的自定義輸入選項(第一行)
Enter鍵上的自定義輸入選項(第二行)

注意:
自定義編輯器選項只會影響軟鍵盤輸入。改變這些選項的值不會影響到使用者在物理鍵盤上按Enter鍵時觸發的事件。

2. 自定義動作

與自定義Enter鍵上顯示的文字一樣重要的是自定義使用者按下此按鍵時所觸發的動作。過載動作的預設行為只需要給相應的檢視加上TextView.OnEditorActionListener。下面繼續修改上面的佈局示例,這次給兩個檢視都加上一個自定義的動作(參見以下程式碼)。

實現了自定義按鍵動作的Activity

public class MyActivity extends Activity implements TextView.OnEditorActionListener{

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        //給檢視新增監聽器
        EditText text1 = (EditText)findViewById(R.id.text1);
        text1.setOnEditorActionListener(this);
        EditText text2 = (EditText)findViewById(R.id.text2);
        text2.setOnEditorActionListener(this);
    }

    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == IME_ACTION_SEARCH){
            //處理搜尋按鍵單擊
            return true;
        }
        if (actionId == IME_ACTION_GO){
            //處理Go按鍵單擊
            return true;
        }
        return false;
    }
}

onEditorAction()返回的布林值會告訴系統應用是否處理了這個事件,或者是否應該將其傳遞給下一個可能的響應者(如果有的話)。所以在實現該方法時一定要返回true,這樣系統就不會再對其他實現進行處理。當然,如果沒有處理這個事件,就可以返回false,這樣系統的其他部分就能對其進行處理。

注意:
如果應用程式自定義為某個鍵盤返回的actionId值,則要注意只會在軟鍵盤IME上進行這種自定義。如果裝置附帶物理鍵盤,Enter鍵就會始終返回值為0的actionId或IME_NULL。