Android键盘显示和隐藏
一、不自動彈出鍵盤:
帶有EditText控件的在第一次顯示的時候會自動獲得focus,并彈出鍵盤,如果不想自動彈出鍵盤,有兩種方法:
方法一:在mainfest文件中把對應的activity設置
android:windowSoftInputMode="stateHidden"或者android:windowSoftInputMode="stateUnchanged"。
|
值 |
描述 |
|
"stateUnspecified" |
軟鍵盤的狀態(是否它是隱藏或可見)沒有被指定。系統將選擇一個合適的狀態或依賴于主題的設置。 這個是為了軟件盤行為默認的設置。 |
|
"stateUnchanged" |
軟鍵盤被保持無論它上次是什么狀態,是否可見或隱藏,當主窗口出現在前面時。 |
|
"stateHidden" |
當用戶選擇該Activity時,軟鍵盤被隱藏——也就是,當用戶確定導航到該Activity時,而不是返回到它由于離開另一個Activity。 |
|
"stateAlwaysHidden" |
軟鍵盤總是被隱藏的,當該Activity主窗口獲取焦點時。 |
|
"stateVisible" |
軟鍵盤是可見的,當那個是正常合適的時(當用戶導航到Activity主窗口時)。 |
|
"stateAlwaysVisible" |
當用戶選擇這個Activity時,軟鍵盤是可見的——也就是,也就是,當用戶確定導航到該Activity時,而不是返回到它由于離開另一個Activity。 |
|
"adjustUnspecified" |
它不被指定是否該Activity主 窗口調整大小以便留出軟鍵盤的空間,或是否窗口上的內容得到屏幕上當前的焦點是可見的。系統將自動選擇這些模式中一種主要依賴于是否窗口的內容有任何布局 視圖能夠滾動他們的內容。如果有這樣的一個視圖,這個窗口將調整大小,這樣的假設可以使滾動窗口的內容在一個較小的區域中可見的。這個是主窗口默認的行為 設置。 |
|
"adjustResize" |
該Activity主窗口總是被調整屏幕的大小以便留出軟鍵盤的空間 |
|
"adjustPan" |
該Activity主窗口并不調整屏幕的大小以便留出軟鍵盤的空間。相反,當前窗口的內容將自動移動以便當前焦點從不被鍵盤覆蓋和用戶能總是看到輸入內容的部分。這個通常是不期望比調整大小,因為用戶可能關閉軟鍵盤以便獲得與被覆蓋內容的交互操作。 |
這種方式編輯框還有光標。隱藏光標的方法:EditText.setCursorVisible(false)。
方法二:可以在布局中放一個隱藏的TextView,然后在onCreate的時候requsetFocus。
注意TextView不要設置Visiable=gone,否則會失效,可以在布局中放一個隱藏的TextView,然后在onCreate的時候requsetFocus。
<TextView
android:id="@+id/text_notuse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"/>
TextView textView = (TextView)findViewById(R.id.text_notuse);
textView.requestFocus();
二、手動顯示和隱藏系統鍵盤
1、方法一(如果輸入法在窗口上已經顯示,則隱藏,反之則顯示)。此方法使用尚不確定,不好使。
InputMethodManagerimm=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0,InputMethodManager.HIDE_NOT_ALWAYS);
2、方法二(view為接受軟鍵盤輸入的視圖,SHOW_FORCED表示強制顯示)
InputMethodManagerimm=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(view,InputMethodManager.SHOW_FORCED);
該方法在activity或者fragment的onCreate(或者onCreateView)函數中去調用,發現并不起作用,這是因為在onCreate中或者其他聲明周期函數(onStart,onResume等)中,該EditText還未被繪制出來,InputMethodManager還不能獲取到該控件的焦點,所以鍵盤并不會顯示,而且manager.showSoftInput函數返回false,告訴你鍵盤并未顯示。所以只有當EditText完全被繪制出來了,才可以去獲取焦點。
解決方法:
edittext.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
InputMethodManager manager = (InputMethodManager) getActivity().getSystemService(getActivity().INPUT_METHOD_SERVICE);
manager.showSoftInput(edittext, 0);
}
});
注意:這個監聽事件里最好不要放toggleSoftInput方法,不然鍵盤會不停閃爍。
3、強制隱藏鍵盤
imm.hideSoftInputFromWindow(view.getWindowToken(),0);
注意:如果第二個參數為HIDE_NOT_ALWAYS,那么當showSoftInput的第二個參數為SHOW_FORCED時,則隱藏不掉。
4、調用隱藏系統默認的輸入法
((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(WidgetSearchActivity.this.getCurrentFocus().getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);(WidgetSearchActivity是當前的Activity)
5、獲取輸入法打開的狀態
InputMethodManagerimm=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
booleanisOpen=imm.isActive();//isOpen若返回true,則表示輸入法打開
6、InputMethodManager的常量:
public static final intHIDE_IMPLICIT_ONLY
hideSoftInputFromWindow(IBinder, int)中的標志,表示如果用戶未顯式地顯示軟鍵盤窗口,則隱藏窗口。
常量值: 1 (0x00000001)
public static final intHIDE_NOT_ALWAYS
hideSoftInputFromWindow(IBinder, int)中的標志,表示軟鍵盤窗口總是隱藏,除非開始時以SHOW_FORCED顯示。
常量值: 2 (0x00000002)
public static final intRESULT_HIDDEN
showSoftInput(View, int, ResultReceiver)和hideSoftInputFromWindow(IBinder, int, ResultReceiver)中ResultReceiver結果代碼標志:軟鍵盤窗口從顯示切換到隱藏時的狀態。
常量值: 3 (0x00000003)
public static final intRESULT_SHOWN
showSoftInput(View, int, ResultReceiver)和hideSoftInputFromWindow(IBinder, int, ResultReceiver)中ResultReceiver結果代碼標志:軟鍵盤窗口從隱藏切換到顯示時的狀態。
常量值: 2 (0x00000002)
public static final intRESULT_UNCHANGED_HIDDEN
showSoftInput(View, int, ResultReceiver)和hideSoftInputFromWindow(IBinder, int, ResultReceiver)中ResultReceiver結果代碼標志:軟鍵盤窗口不變保持隱藏時的狀態。
常量值: 1 (0x00000001)
public static final intRESULT_UNCHANGED_SHOWN
showSoftInput(View, int, ResultReceiver)和hideSoftInputFromWindow(IBinder, int, ResultReceiver)中ResultReceiver結果代碼標志:軟鍵盤窗口不變保持顯示時的狀態。
常量值: 0 (0x00000000)
public static final intSHOW_FORCED
showSoftInput(View, int)標志,表示用戶強制打開輸入法(如長按菜單鍵),一直保持打開直至只有顯式關閉。
常量值: 2 (0x00000002)
public static final intSHOW_IMPLICIT
showSoftInput(View, int)標志,表示隱式顯示輸入窗口,非用戶直接要求。窗口可能不顯示。
常量值: 1 (0x00000001)
四、公共方法
public voiddisplayCompletions(View view, CompletionInfo[] completions)
(譯者注:輸入法自動完成)
public InputMethodSubtypegetCurrentInputMethodSubtype()
(譯者注:獲取當前輸入法類型?)
public List<InputMethodInfo>getEnabledInputMethodList()
(譯者注:獲取已啟用輸入法列表?)
public List<InputMethodSubtype> getEnabledInputMethodSubtypeList (InputMethodInfo imi, boolean allowsImplicitlySelectedSubtypes)
public List<InputMethodInfo>getInputMethodList()
(譯者注:獲取輸入法列表)
public Map<InputMethodInfo, List<InputMethodSubtype>>getShortcutInputMethodsAndSubtypes()
public voidhideSoftInputFromInputMethod(IBinder token, int flags)
關閉/隱藏輸入法軟鍵盤區域,用戶不再看到或與其交互。只能由當前激活輸入法調用,因需令牌(token)驗證。
參數
token在輸入法啟動時提供令牌驗證,驗證后可對其進行操作。
flags提供額外的操作標志。當前可以為0或HIDE_IMPLICIT_ONLY,HIDE_NOT_ALWAYS等位設置。
public booleanhideSoftInputFromWindow(IBinder windowToken, int flags)
hideSoftInputFromWindow(IBinder, int, ResultReceiver)的無返回值版:從窗口上下文中確定當前接收輸入的窗口,隱藏其輸入法窗口
參數
windowToken由窗口請求View.getWindowToken()返回得到的令牌(token)。
flags提供額外的操作標志。當前可以為0或HIDE_IMPLICIT_ONLY位設置。
public booleanhideSoftInputFromWindow(IBinder windowToken, int flags, ResultReceiver resultReceiver)
從窗口上下文中確定當前接收輸入的窗口,要求隱藏其軟鍵盤窗口。它可由用戶調用并得到結果而不僅僅是顯式要求輸入法窗口隱藏。
參數
windowToken由窗口請求View.getWindowToken()返回得到的令牌(token)。
flags提供額外的操作標志。當前可以為0或HIDE_IMPLICIT_ONLY位設置。
resultReceiver 如不為空,當IME處理請求告訴你完成時調用。你收到的結果碼可以是RESULT_UNCHANGED_SHOWN,RESULT_UNCHANGED_HIDDEN,RESULT_SHOWN,或RESULT_HIDDEN。
public voidhideStatusIcon(IBinder imeToken)
(譯者注:隱藏狀態欄圖標?)
public booleanisAcceptingText()
當前服務視圖接受全文編輯返回真。沒有輸入法聯接為false,這時其只能處理原始按鍵事件。
public booleanisActive(View view)
視圖為當前輸入的激活視圖時返回真。
public booleanisActive()
輸入法中的任意視圖激活時返回真。
public booleanisFullscreenMode()
判斷相關輸入法是否以全屏模式運行。全屏時,完全覆蓋你的UI時,返回真,否則返回假。
public booleanisWatchingCursor(View view)
如當前輸入法要看到輸入編輯者的光標位置時返回真。
public voidrestartInput(View view)
如有輸入法聯接至視圖,重啟輸入以顯示新的內容。可在以下情況時調用此方法:視圖的文字導致輸入法外觀變化或有按鍵輸入流,如應用程序調用TextView.setText()時。
參數
view文字發生變化的視圖。
public voidsendAppPrivateCommand(View view, String action, Bundle data)
對當前輸入法調用InputMethodSession.appPrivateCommand()。
參數
view可選的發送命令的視圖,如你要發送命令而不考慮視圖附加到輸入法,此項可以為空。
action執行的命令名稱。必須是作用域的名稱,如前綴包名稱,這樣不同的開發者就不會創建沖突的命令。
data命令中包含的任何數據。
public booleansetCurrentInputMethodSubtype(InputMethodSubtype subtype)
(譯者注:此方法為3.0中新增的方法)
public voidsetInputMethod(IBinder token, String id)
強制切換到新輸入法部件。只能由持有token的應用程序(application)或服務(service)調用當前激活輸入法。
參數
token在輸入法啟動時提供令牌驗證,驗證后可對其進行操作。
id 切換到新輸入法的唯一標識。
public voidsetInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype)
強制切換到一個新的輸入法和指定的類型。只能由持有token的應用程序(application)或服務(service)調用當前激活輸入法。(譯者注:此方法為3.0中新增的方法)
參數
token在輸入法啟動時提供令牌驗證,驗證后可對其進行操作。
id 切換到新輸入法的唯一標識。
subtype切換到新輸入法的新類型。
public voidshowInputMethodAndSubtypeEnabler(String topId)
(譯者注:此方法為3.0中新增的方法)
public voidshowInputMethodPicker()
(譯者注:顯示輸入法菜單列表)
public booleanshowSoftInput(View view, int flags, ResultReceiver resultReceiver)
如需要,顯式要求當前輸入法的軟鍵盤區域向用戶顯示。當用戶與視圖交互,用戶表示要開始執行輸入操作時,可以調用此方法。
參數
view當前焦點視圖,可接受軟鍵盤輸入。
flags提供額外的操作標志。當前可以是0或SHOW_IMPLICIT位設置。
resultReceiver如不為空,當IME處理請求告訴你完成時調用。你收到的結果碼可以是RESULT_UNCHANGED_SHOWN,RESULT_UNCHANGED_HIDDEN,RESULT_SHOWN,或RESULT_HIDDEN。
public booleanshowSoftInput(View view, int flags)
showSoftInput(View, int, ResultReceiver)的無返回值版:如需要,顯式要求當前輸入法的軟鍵盤區域向用戶顯示。
參數
view當前焦點視圖,可接受軟鍵盤輸入。
flags提供額外的操作標志。當前可以是0或SHOW_IMPLICIT位設置。
public voidshowSoftInputFromInputMethod(IBinder token, int flags)
顯示輸入法的軟鍵盤區域,這樣用戶可以到看到輸入法窗口并能與其交互。只能由當前激活輸入法調用,因需令牌(token)驗證。
參數
token在輸入法啟動時提供令牌驗證,驗證后可對其進行操作。
flags提供額外的操作標志。可以是0或SHOW_IMPLICIT,SHOW_FORCED位設置。
public voidshowStatusIcon(IBinder imeToken, String packageName, int iconId)
(譯者注:顯示狀態欄圖標?)
public booleanswitchToLastInputMethod(IBinder imeToken)
public voidtoggleSoftInput(int showFlags, int hideFlags)
(譯者注:切換軟鍵盤)
public voidtoggleSoftInputFromWindow(IBinder windowToken, int showFlags, int hideFlags)
本方法切換輸入法的窗口顯示。如輸入窗口已顯示,它隱藏。如無輸入窗口則顯示。
參數
windowToken 由窗口請求View.getWindowToken()返回得到的令牌(token)。
showFlags提供額外的操作標志。當前可以為0或HIDE_IMPLICIT_ONLY位設置。
hideFlags提供額外的操作標志。可以是0或HIDE_IMPLICIT_ONLY,HIDE_NOT_ALWAYS位設置。
public voidupdateCursor(View view, int left, int top, int right, int bottom)
返回窗口的當前光標位置。
public voidupdateExtractedText(View view, int token, ExtractedText text)
(譯者注:當內容變化時文本編輯器調用此方法,通知其新提取文本。)
public voidupdateSelection(View view, int selStart, int selEnd, int candidatesStart, int candidatesEnd)
返回當前選擇區域。
7、點擊非輸入框意外的區域時,收起鍵盤的方法。
考慮代碼的復用性,以下代碼均實現在基類BaseActivity中。
首先我們要重寫dispatchTouchEvent()把操作放在用戶點擊的時候
/** * 點擊空白區域隱藏鍵盤. */ @Override public boolean dispatchTouchEvent(MotionEvent me) { if (me.getAction() == MotionEvent.ACTION_DOWN) { //把操作放在用戶點擊的時候 View v = getCurrentFocus(); //得到當前頁面的焦點,ps:有輸入框的頁面焦點一般會被輸入框占據 if (isShouldHideKeyboard(v, me)) { //判斷用戶點擊的是否是輸入框以外的區域 hideKeyboard(v.getWindowToken()); //收起鍵盤 } } return super.dispatchTouchEvent(ev); }
/**
* 根據EditText所在坐標和用戶點擊的坐標相對比,來判斷是否隱藏鍵盤,因為當用戶點擊EditText時則不能隱藏
*
* @param v
* @param event
* @return
*/
private boolean isShouldHideKeyboard(View v, MotionEvent event) {
if (v != null && (v instanceof EditText)) { //判斷得到的焦點控件是否包含EditText
int[] l = {0, 0};
v.getLocationInWindow(l);
int left = l[0], //得到輸入框在屏幕中上下左右的位置
top = l[1],
bottom = top + v.getHeight(),
right = left + v.getWidth();
if (event.getX() > left && event.getX() < right
&& event.getY() > top && event.getY() < bottom) {
// 點擊位置如果是EditText的區域,忽略它,不收起鍵盤。
return false;
} else {
return true;
}
}
// 如果焦點不是EditText則忽略
return false;
}
/**
* 獲取InputMethodManager,隱藏軟鍵盤
* @param token
*/
private void hideKeyboard(IBinder token) {
if (token != null) {
InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);
}
}
鳴謝:
http://blog.csdn.net/h7870181/article/details/8332991
http://blog.csdn.net/pi9nc/article/details/9196779
http://blog.csdn.net/lxlmycsdnfree/article/details/60962731
https://www.jianshu.com/p/07963a45524b
總結
以上是生活随笔為你收集整理的Android键盘显示和隐藏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我花开后百花杀的寓意是什么
- 下一篇: 乘风破浪,遇见最美Windows 11之