Android EditText關於imeOptions的設定和響應

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第15天,點選檢視活動詳情

v2-e7788a7ca065a05c0bcde20abe34e9f3_1440w.jpg

日常開發中,最繞不開的一個控制元件就是EditText,隨之避免不了的則是對其軟鍵盤事件的監聽,隨著需求的不同對使用者輸入的軟鍵盤要求也不同,有的場景需要使用者輸入完畢後,有一個確認按鈕,有的場景需要的是回車,有的場景需要使用者輸入後進入下一項或者搜尋,所幸的是,大部分需求場景通過修改原生設定就可滿足,只要極少情況下才需要去寫自定義鍵盤。而關於EditText喚起的軟鍵盤中回車的功能可以通過imeOptions的設定來進行相應的設定。

其使用方式僅通過在xml中宣告即可:

<EditText             ...             android:imeOptions="actionSend"/>

常用屬性

如果不特殊宣告,右下角按鍵則為回車鍵。其常用屬性及相應功能設定如下: 屬性 | 右下角按鍵顯示及常見應用場景 | | --------------- | ----------------------------------- | | actionGo | 右下角按鍵顯示“開始” | | actionSearch | 右下角顯示放大鏡,對應搜尋功能場景 | | actionSend | 右下角按鍵內容為"傳送",一般用於即時聊天頁面 | | actionNext | 右下角按鍵內容為“下一步”或者“下一項”,會跳到下一個EditText | | actionDone | 右下角按鍵內容為“完成” | | actionNone | 無任何提示 | | flagNoExtractUi | 使軟鍵盤不全屏顯示,只佔用一部分螢幕,右下角按鍵為預設回車鍵在指定imeOptions後,還要新增android:inputType="text"屬性。

也可以通過程式碼去設定對應屬性,如下:

editText.setInputType(EditorInfo.TYPE_CLASS_TEXT); editText.setImeOptions(EditorInfo.IME_ACTION_...);

其屬性與程式碼中設定的常量關係為: 屬性 | 對應常量 | | ---------------------- | --------------------------------- | | actionGo | EditorInfo.IME_ACTION_GO | | actionSearch | EditorInfo.IME_ACTION_SEARCH | | actionSend | EditorInfo.IME_ACTION_SEND | | actionNext | EditorInfo.IME_ACTION_NEXT | | actionDone | EditorInfo.IME_ACTION_DONE | | actionNone | EditorInfo.IME_ACTION_NONE | | actionUnspecified(未指定) | EditorInfo.IME_ACTION_UNSPECIFIED

監聽

對應的EditText可以設定相應的監聽,editText.setOnEditorActionListener,在監聽的onEditorAction()中通過返回的actionId引數來判斷觸發的對應事件。例如以下示例:

xml中簡單設定一個EditText: ```

對應在Activity中對其進行事件監聽: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EditText mEdtView = findViewById(R.id.edt_view); mEdtView.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { switch (actionId){ case EditorInfo.IME_ACTION_DONE: Toast.makeText(MainActivity.this, "IME_ACTION_DONE", Toast.LENGTH_SHORT).show(); break; case EditorInfo.IME_ACTION_GO: Toast.makeText(MainActivity.this, "IME_ACTION_GO", Toast.LENGTH_SHORT).show(); break; case EditorInfo.IME_ACTION_NEXT: Toast.makeText(MainActivity.this, "IME_ACTION_NEXT", Toast.LENGTH_SHORT).show(); break; case EditorInfo.IME_ACTION_NONE: Toast.makeText(MainActivity.this, "IME_ACTION_NONE", Toast.LENGTH_SHORT).show(); break; case EditorInfo.IME_ACTION_PREVIOUS: Toast.makeText(MainActivity.this, "IME_ACTION_PREVIOUS", Toast.LENGTH_SHORT).show(); break; case EditorInfo.IME_ACTION_SEARCH: Toast.makeText(MainActivity.this, "IME_ACTION_SEARCH", Toast.LENGTH_SHORT).show(); break; case EditorInfo.IME_ACTION_SEND: Toast.makeText(MainActivity.this, "IME_ACTION_SEND", Toast.LENGTH_SHORT).show(); break; case EditorInfo.IME_ACTION_UNSPECIFIED: Toast.makeText(MainActivity.this, "IME_ACTION_UNSPECIFIED", Toast.LENGTH_SHORT).show(); break; default: break; } return true; } }); } ``` 其對應效果為:

Edit-Text-Gif.gif

對應吐司也驗證了我們程式碼的執行,我們再在xml中刪除對應屬性,用程式碼的形式宣告試試。

xml中:

```

可見,其餘無變動,對應activity的修改則是在設定監聽前設定對應屬性: ... mEdtView.setImeOptions(EditorInfo.IME_ACTION_SEND); ... ``` 其效果為:

Edit-Text-Gif2.gif

可見,程式碼中設定效果則一樣,也許你會疑問,為什麼點選右下角按鍵後還不能收起軟鍵盤,系統中是沒有這樣主動行為的,需要我們自己來呼叫以下方法即可:

InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(context.getWindow().getDecorView().getWindowToken(), 0);

重複響應問題

這裡需要注意的是,onEditorAction中,如果返回的是false,則onEditorAction中的程式碼可能會呼叫兩次,原因不難理解,系統會首先判斷使用者實現的方法onEditorActionListener.onEditorAction(this, actionCode, null)的返回值,一旦返回true,會立即return,因此係統的處理被直接跳過。

設定無效問題

當設定了android:maxLines="1" 屬性時,有可能出現設定無效問題,這裡要改為android:singleLine="true"此屬性即可。當然,有可能個別的機型還有其他適配問題,比如三星等等,有遇見的朋友可以留言互相交流。