最近從新設計了一遍項目中的搜索欄,可是目前這個輸入框每次填完搜索內容,都須要去按下右邊的搜索按鈕,感受比較麻煩。可是看到不少應用,填完內容後輸入框右下角按鈕直接會變成搜索按鈕。平時對這方面瞭解比較少,故在此總結下Android軟鍵盤響應事件。java
要想實現這個小功能,就不得不說這個屬性,對應代碼中的方法是:android
void setImeOptions(int imeOptions)
和int getImeOptions()
。bash
imeOptions
經常使用的有如下幾種:ide
意思都很好理解 ,其中默認動做是actionUnspecified
,在代碼中這些值存儲在EditorInfo
類中,以IME開頭,如EditorInfo.IME_ACTION_GO
。因此上面咱們須要實現的搜索功能只是這些動做中的一種。另外還須要設置一個屬性,否則沒法生效:佈局
android:singleLine="true"
ui
個人理解是,若是不設置限制單行,那麼右下角會被換行按鈕佔用,這個功能是高於鍵盤動做事件優先級的。 另外可能有些輸入法還要求設置: android:inputType="text"
this
不過我實測不設置也能夠(固然爲了兼容性仍是建議設一下)。好了,這樣設完以後咱們就能夠在代碼中監聽這個動做的事件了:spa
mEditText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
String text = mEditText.getText().toString();
if (TextUtils.isEmpty(text)) {
Toast.makeText(MainActivity.this, "請輸入關鍵字", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "輸入了" + text, Toast.LENGTH_SHORT).show();
}
return true;
}
return false;
}
});
複製代碼
看下效果:設計
public void onEditorAction(int actionCode) {
final Editor.InputContentType ict = mEditor == null ? null : mEditor.mInputContentType;
if (ict != null) {
if (ict.onEditorActionListener != null) {
if (ict.onEditorActionListener.onEditorAction(this,
actionCode, null)) {
return;
}
}
......執行默認動做
複製代碼
在源碼中看出,系統實現的默認動做只有三個:code
if (actionCode == EditorInfo.IME_ACTION_NEXT) {
View v = focusSearch(FOCUS_FORWARD);
if (v != null) {
if (!v.requestFocus(FOCUS_FORWARD)) {
throw new IllegalStateException("focus search returned a view "
+ "that wasn't able to take focus!");
}
}
return;
} else if (actionCode == EditorInfo.IME_ACTION_PREVIOUS) {
View v = focusSearch(FOCUS_BACKWARD);
if (v != null) {
if (!v.requestFocus(FOCUS_BACKWARD)) {
throw new IllegalStateException("focus search returned a view "
+ "that wasn't able to take focus!");
}
}
return;
} else if (actionCode == EditorInfo.IME_ACTION_DONE) {
InputMethodManager imm = InputMethodManager.peekInstance();
if (imm != null && imm.isActive(this)) {
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
return;
}
}
複製代碼
有一點須要提一下:上面代碼這麼設置,點完搜索按鈕,事件響應了但輸入框是不會消失的,因此這裏咱們能夠取巧下:處理完咱們的動做後直接把動做設置爲IME_ACTION_DONE
,而後返回false,這樣就能夠繼續執行EditorInfo.IME_ACTION_DONE
中的代碼,從而實如今點完搜索按鈕後隱藏輸入框:
mEditText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
String text = mEditText.getText().toString();
if (TextUtils.isEmpty(text)) {
//若是沒輸入內容就不隱藏了
Toast.makeText(MainActivity.this, "請輸入關鍵字", Toast.LENGTH_SHORT).show();
return true;
} else {
Toast.makeText(MainActivity.this, "輸入了" + text, Toast.LENGTH_SHORT).show();
mEditText.setImeOptions(EditorInfo.IME_ACTION_DONE);
return false;
}
}
return false;
}
});
複製代碼
android:singleLine="true"
,可是咱們想換行怎麼辦? 在代碼中這樣設置就好了:mEditText.setHorizontallyScrolling(false);
mEditText.setMaxLines(4);
複製代碼
在佈局文件中設置是無效的,應該也是優先級的問題。加第一行代碼是由於EditTextview內容超過一行是不會換行的而是左右滾動。
想自定義鍵盤上事件響應的按鈕是不行的,只能從已經設置好的幾個動做中選擇,因爲第三方輸入法的不一樣,有些動做不會響應,顯示圖標也不盡相同。
咱們是根據actionId
而不是直接採用mEditText.getImeOptions()
,兩個值初始時是同樣的,但第一次軟件盤事件響應後,後者值就變了,而actionId仍是原來的。軟鍵盤右下角按鈕的動做是取決於actionId
的,這樣咱們也就不須要在鍵盤消失後將mEditText
的動做還原。