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