EditText 是很常見的控件,常見屬性是必須要了解的。
類似 InputType 和 imeOptions 等屬性和軟鍵盤都有很強的互動。
異常
java.lang.StringIndexOutOfBoundsException
出錯堆棧:
- InputType
指定輸入數據類型,這個屬性會與軟鍵盤互動。
<EditText
android:inputType=""
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
屬性一覽:
inputType | 說明 |
---|---|
android:inputType="textUri" | URI格式 |
android:inputType="textEmailAddress" | 電子郵件地址格式 |
android:inputType="textEmailSubject" | 郵件主題格式 |
android:inputType="textPassword" | 密碼格式 |
android:inputType="number" | 數字格式 |
android:inputType="numberPassword" | 數字密碼格式 |
android:inputType="textVisiblePassword" | 密碼可見格式 |
android:inputType="textCapCharacters" | 前3個輸入普通字符 |
android:inputType="textCapWords" | 單詞首字母大小 |
android:inputType="textCapSentences" | 僅第一個字母大寫 |
android:inputType="textAutoCorrect" | 前兩個自動完成 |
android:inputType="textAutoComplete" | 前兩個自動完成 |
android:inputType="textMultiLine" | 多行輸入 |
android:inputType="textImeMultiLine" | 輸入法多行(不一定支持) |
android:inputType="textNoSuggestions" | 不提示 |
android:inputType="textShortMessage" | 短消息格式 |
android:inputType="textLongMessage" | 長消息格式 |
android:inputType="textPersonName" | 人名格式 |
android:inputType="textPostalAddress" | 郵政格式 |
android:inputType="textWebEditText" | 作為網頁表單的文本格式 |
android:inputType="textFilter" | 文本篩選格式 |
android:inputType="textPhonetic" | 拼音輸入格式 |
android:inputType="numberSigned" | 有符號數字格式 |
android:inputType="numberDecimal" | 可以帶小數點的浮點格式 |
android:inputType="phone" | 撥號鍵盤 |
android:inputType="datetime" | 日期時間鍵盤 |
android:inputType="date" | 日期鍵盤 |
android:inputType="time" | 時間鍵盤 |
以上屬性會影響彈出的軟鍵盤的屬性,
比如設置為 android:inputType="number"
的時候,軟鍵盤會自動進入到數字鍵盤。
設置為 android:inputType="textEmailSubject"
的時候,軟鍵盤可能會提供一些快捷的按鈕:(與系統相關)
inputType
也可以在代碼中設置
mEditText.setInputType(EditorInfo.TYPE_CLASS_TEXT);
mEditText.setInputType(EditorInfo.TYPE_TEXT_VARIATION_URI);//英文鍵盤
- 監聽函數
//輸入監聽
mEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//輸入過程中調用,可以獲取到輸入內容到長度
}
@Override
public void afterTextChanged(Editable s) {
//輸入完成后調用,獲取完整到輸入內容
}
});
//軟鍵盤按鍵監聽
mEditText.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {
//按下 Enter 鍵
return true;
}
return false;
}
});
- imeOptions
決定軟鍵盤中 Enter 顯示的內容和操作
/**
*
*actionSearch 搜索
*actionSend 發送
*actionNext 下一步
*actionDone 完成
*/
<EditText
android:imeOptions=""
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
值得一提是,在沒有指定 InputType 的時候,imeOptions 屬性可能不起作用。
這時候可以將 InputType 指定為 text,或者 singleLine 設置為 true。
- 屏蔽系統自帶的長按復制粘貼:
//低版本可以設置長按監聽為 false 即可
mEditTxt.setLongClickable(false);
mEditTxt.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
return false;
}
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return false;
}
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
});
- 關閉軟鍵盤
//直接關閉軟鍵盤
InputMethodManager manager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
manager.hideSoftInputFromWindow(edit.getWindowToken(),0);
//EditText 失去焦點,則軟鍵盤關閉
mEditText.clearFocus();
//EditText 不彈出軟鍵盤
mEditText.setInputType(InputType.TYPE_NULL);
- windowSoftInputMode
決定窗口與軟鍵盤的交互模式。
在 AndroidManifest 中設置:
<activity
android:name=".main.MainActivity"
android:windowSoftInputMode="stateHidden|adjustResize" />
屬性一覽:
windowSoftInputMode | 說明 |
---|---|
stateAlwaysVisible | 當用戶選擇 Activity 時 — 也就是說,當用戶確實是向前導航到 Activity,而不是因離開另一 Activity 而返回時 — 顯示軟鍵盤。 |
adjustUnspecified | 不指定 Activity 的主窗口是否調整尺寸以為軟鍵盤騰出空間,或者窗口內容是否進行平移以在屏幕上顯露當前焦點。 系統會根據窗口的內容是否存在任何可滾動其內容的布局視圖來自動選擇其中一種模式。 如果存在這樣的視圖,窗口將進行尺寸調整,前提是可通過滾動在較小區域內看到窗口的所有內容。這是對主窗口行為的默認設置。 |
adjustResize | 始終調整 Activity 主窗口的尺寸來為屏幕上的軟鍵盤騰出空間。 |
adjustPan | 不調整 Activity 主窗口的尺寸來為軟鍵盤騰出空間, 而是自動平移窗口的內容,使當前焦點永遠不被鍵盤遮蓋,讓用戶始終都能看到其輸入的內容。 這通常不如尺寸調正可取,因為用戶可能需要關閉軟鍵盤以到達被遮蓋的窗口部分或與這些部分進行交互。 |
stateVisible | 在正常的適宜情況下(當用戶向前導航到 Activity 的主窗口時)顯示軟鍵盤。 |
stateAlwaysHidden | 當 Activity 的主窗口有輸入焦點時始終隱藏軟鍵盤。 |
stateUnspecified | 不指定軟鍵盤的狀態(隱藏還是可見)。 將由系統選擇合適的狀態,或依賴主題中的設置。這是對軟鍵盤行為的默認設置。 |
stateUnchanged | 當 Activity 轉至前臺時保留軟鍵盤最后所處的任何狀態,無論是可見還是隱藏。 |
stateHidden | 當用戶選擇 Activity 時 — 也就是說,當用戶確實是向前導航到 Activity,而不是因離開另一 Activity 而返回時 — 隱藏軟鍵盤。 |
實際上關于軟鍵盤的遮擋的問題有好幾種解決的方法,比如在跟布局上加一個 ScrollView;或者監聽軟鍵盤的彈出以手動移動布局;
- 樣式
因為用的主題自帶的 EditText 樣式和需求差的有點遠,還好自定義并不麻煩:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false">
<shape>
<stroke android:width="1.5px" android:color="@color/grayBg"></stroke>
<solid android:color="#efefef"></solid>
<corners android:radius="4dp"></corners>
</shape>
</item>
<item android:state_pressed="true">
<shape>
<stroke android:width="1.5px" android:color="@color/grayBg"></stroke>
<solid android:color="#efefef"></solid>
<corners android:radius="4dp"></corners>
</shape>
</item>
<item android:state_focused="true">
<shape>
<stroke android:width="1.5px" android:color="@color/colorPrimary"></stroke>
<solid android:color="@color/white"></solid>
<corners android:radius="4dp"></corners>
</shape>
</item>
<item >
<shape>
<stroke android:width="1.5px" android:color="@color/grayBg"></stroke>
<solid android:color="@color/white"></solid>
<corners android:radius="4dp"></corners>
</shape>
</item>
</selector>
- Dialog 中的 EditText 好像沒辦法自動彈出軟鍵盤:
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
((InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
.showSoftInput(receiptEdit,InputMethodManager.SHOW_FORCED);
}
});
- android:selectAllOnFocus="true"
在獲取焦點時全選內容。