1. 程式人生 > >Android監聽軟鍵盤迴車事件

Android監聽軟鍵盤迴車事件

在Android開發中,難免會碰到一些”意外“。比如輸入法軟按鍵監聽問題,因為第三方輸入法各有不同(對一些按鍵事件作了一些特殊的處理),所以有時有些程式碼會“失靈”。假設一個場景,EditText監聽回車事件,回車後就傳送輸入的內容,一般有以下4種處理方式:

假設場景圖:


1.setImeOptions

用程式碼設定:

mEditText.setImeOptions(EditorInfo.IME_ACTION_SEND);
或者在佈局檔案中設定:
<EditText 
	...
        android:imeOptions="actionSend"
        />

2.setOnKeyListener

mEditText.setOnKeyListener(new View.OnKeyListener() {
			
			@Override
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				//這裡注意要作判斷處理,ActionDown、ActionUp都會回撥到這裡,不作處理的話就會呼叫兩次
				if (KeyEvent.KEYCODE_ENTER == keyCode && KeyEvent.ACTION_DOWN == event.getAction()) {
					//處理事件
					return true;
				}
				return false;
			}
		});
但是,這個介面有可能會“失靈”,看說明文件:
Register a callback to be invoked when a hardware key is pressed in this view. Key presses in software input methods will generally not trigger the methods of this listener.
可知,這個介面主要是針對物理按鍵,軟按鍵通常不會觸發這個方法(存在可能性)。因此,這個方法不推薦。

3.dispatchKeyEvent

也可以在Activity或者Dialog裡覆寫dispatchKeyEvent來達到目的:

@Override
	public boolean dispatchKeyEvent(KeyEvent event) {
		//這裡注意要作判斷處理,ActionDown、ActionUp都會回撥到這裡,不作處理的話就會呼叫兩次
		if (KeyEvent.KEYCODE_ENTER == event.getKeyCode() && KeyEvent.ACTION_DOWN == event.getAction()) {
			//處理事件
			return true;
		}
		return super.dispatchKeyEvent(event);
	}

4.setOnEditorActionListener

這個方法應該是最正統也最合適的,一般的做法:

mEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
			
			@Override
			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
				if (actionId == EditorInfo.IME_ACTION_SEND) {
					//處理事件
				}
				return false;
			}
		});
當然這個前提是要用1中的方法設定ImeOption,也就是改變軟鍵盤上回車鍵的Action。但是,在實際使用中,發現在不同輸入法上效果不同,某些輸入法上根本不會改變回車鍵的Action,也就是actionId != EditorInfo.IME_ACTION_SEND,而是==EditorInfo.IME_ACTION_DONE。往往遇到如此問題時,可能第一反應就是選擇2、3方法,但是2、3方法也有可能不奏效。那該怎麼去適配軟鍵盤呢?目光回到onEditorAction上,發現此回撥介面帶有3個引數,再看1、2、3方法,其實用到的就是IME_ACTION_XX和KeyEvent物件,而onEditorAction回撥引數就有這兩個。我們只需要在onEditorAction裡再稍作處理就行了。比如:
mEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
			
			@Override
			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
				//當actionId == XX_SEND 或者 XX_DONE時都觸發
				//或者event.getKeyCode == ENTER 且 event.getAction == ACTION_DOWN時也觸發
				//注意,這是一定要判斷event != null。因為在某些輸入法上會返回null。
				if (actionId == EditorInfo.IME_ACTION_SEND
						|| actionId == EditorInfo.IME_ACTION_DONE
						|| (event != null && KeyEvent.KEYCODE_ENTER == event.getKeyCode() && KeyEvent.ACTION_DOWN == event.getAction())) {
					//處理事件
				}
				return false;
			}
		});

文件說明:
Set a special listener to be called when an action is performed on the text view. This will be called when the enter key is pressed, or when an action supplied to the IME is selected by the user. Setting this means that the normal hard key event will not insert a newline into the text view, even if it is multi-line; holding down the ALT modifier will, however, allow the user to insert a newline character.

總結:軟鍵盤迴車鍵事件只需要用方法4就可以輕鬆解決,也是最合適的方法。

希望對大家有所幫助,謝謝!

——《Android細節隨筆》,於2014.4.24