InputMethodService為我們的輸入法創建了一個Dialog,并且將該Dialog的Window的某些參數(如Gravity)進行了設置,使之能夠在底部或者全屏顯示。當我們點擊輸入框時,系統對活動主窗口進行調整,從而為輸入法騰出相應的空間,然后將該Dialog顯示在底部,或者全屏顯示。
軟鍵盤顯示的調整
Android定義了一個屬性,名字為windowSoftInputMode, 這個屬性用于設置Activity主窗口與軟鍵盤的交互模式,用于避免軟鍵盤遮擋內容的問題。我們可以在AndroidManifet.xml中對Activity進行設置。如:android:windowSoftInputMode=”stateUnchanged|adjustPan”。 該屬性可選的值有兩部分,一部分為軟鍵盤的狀態控制,控制軟鍵盤是隱藏還是顯示,另一部分是Activity窗口的調整,以便騰出空間展示軟鍵盤。 android:windowSoftInputMode的屬性設置必須是下面中的一個值,或一個”state”值加一個”adjust”值的組合,各個值之間用 | 分開。
stateUnspecified-未指定狀態:當我們沒有設置android:windowSoftInputMode屬性的時候,軟件默認采用的就是這種交互方式,系統會根據界面采取相應的軟鍵盤的顯示模式。
stateUnchanged-不改變狀態:當前界面的軟鍵盤狀態,取決于上一個界面的軟鍵盤狀態,無論是隱藏還是顯示。
stateHidden-隱藏狀態:當設置該狀態時,軟鍵盤總是被隱藏,不管是否有輸入的需求。
stateAlwaysHidden-總是隱藏狀態:當設置該狀態時,軟鍵盤總是被隱藏,和stateHidden不同的是,當我們跳轉到下個界面,如果下個頁面的軟鍵盤是顯示的,而我們再次回來的時候,軟鍵盤就會隱藏起來。
stateVisible-可見狀態:當設置為這個狀態時,軟鍵盤總是可見的,即使在界面上沒有輸入框的情況下也可以強制彈出來出來。
stateAlwaysVisible-總是顯示狀態:當設置為這個狀態時,軟鍵盤總是可見的,和stateVisible不同的是,當我們跳轉到下個界面,如果下個頁面軟鍵盤是隱藏的,而我們再次回來的時候,軟鍵盤就會顯示出來。
adjustUnspecified-未指定模式:設置軟鍵盤與軟件的顯示內容之間的顯示關系。當你跟我們沒有設置這個值的時候,這個選項也是默認的設置模式。在這中情況下,系統會根據界面選擇不同的模式。
adjustResize-調整模式:該模式下窗口總是調整屏幕的大小用以保證軟鍵盤的顯示空間;這個選項不能和adjustPan同時使用,如果這兩個屬性都沒有被設置,系統會根據窗口中的布局自動選擇其中一個。
adjustPan-默認模式:該模式下通過不會調整來保證軟鍵盤的空間,而是采取了另外一種策略,系統會通過布局的移動,來保證用戶要進行輸入的輸入框肯定在用戶的視野范圍里面,從而讓用戶可以看到自己輸入的內容。
案例
沒有滾動布局xml
對于沒有滾動控件的布局來說,adjustPan就是默認的設置,比如我們案例應用中的文本輸入8,上面的文本輸入框123和按鈕都會被頂上去,且頁面布局不可以滾動。
對于沒有滾動控件的布局來說,整個布局會網上偏移(包括標題等)以保證輸入框的可見。如果有滾動控件,那么就是內容網上偏移,標題不會動,還可以通關滾動來查看被頂上去的內容,而這點是不可滾動的布局所不具備的
沒有滾動的布局
有滾動布局xml
對于有滾動控件的布局,則是采用的adjustResize方式,比如我們案例應用中的文本輸入8,上面的文本輸入框123和按鈕都會被頂上去,可以通過滾動來查看被頂上去的內容。
** 根據這一原理,我們就可以把開發中遇到的軟鍵盤遮擋頁面的問題,利用ScrollView當做根布局,讓系統采用adjustResize模式,很好地解決這一問題。**
自動彈出軟鍵盤
有時候需要一進入Activity后就自動彈出軟鍵盤,可以通過設置一個時間函數來實現,具體寫法如下:
方法一:
Timer timer=new Timer();
timer.schedule(new TimerTask() {
public void run() {
InputMethodManager inputMethodManager= (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
} }, 1000); // 秒后自動彈出
方法二:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
InputMethodManager inputManager =(InputMethodManager) etInput.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.showSoftInput(etInput, 0);
}},1000);// 1秒后自動彈出
不自動彈出軟鍵盤
有時進入Activity后不希望系統自動彈出軟鍵盤,我們可以按照下面的方法來實現:
方法一:
在AndroidMainfest.xml中選擇那個activity,設置windowSoftInputMode屬性為adjustUnspecified|stateHidden
Android:label="@string/app_name"
Android:windowSoftInputMode="adjustUnspecified|stateHidden"
Android:configChanges="orientation|keyboardHidden">
方法二:
讓EditText失去焦點,使用EditText的clearFocus方法
EditText edit=(EditText)findViewById(R.id.edit);
edit.clearFocus();
方法三:
強制隱藏Android輸入法窗口
EditText edit=(EditText)findViewById(R.id.edit);
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(edit.getWindowToken(),0);
方法四:
EditText始終不彈出軟件鍵盤
EditText edit=(EditText)findViewById(R.id.edit);
edit.setInputType(InputType.TYPE_NULL);
EditText設置ScrollView壓縮背景圖片解決辦法
在你的Activity里加上
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
動態關閉軟鍵盤
有時希望根據條件動態關閉軟鍵盤,我們可以使用InputMethodManager類,按照下面的方法來實現:
方法一:
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); //得到InputMethodManager的實例
if (imm.isActive()) {//如果開啟
//關閉軟鍵盤,開啟方法相同,這個方法是切換開啟與關閉狀態的
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT,InputMethodManager.HIDE_NOT_ALWAYS);
}
//這個方法實際是軟鍵盤的開關方法,調用一次打開軟鍵盤再調用一次關閉軟鍵盤,實際上可能并沒有那么使用
方法二:
強制隱藏軟鍵盤,這個方法倒是很實用。
public void KeyBoardCancle() {
View view = getWindow().peekDecorView();
if (view != null) {
InputMethodManager inputmanger = (InputMethodManager) getSystemService(ActivityBase.INPUT_METHOD_SERVICE);
inputmanger.hideSoftInputFromWindow(view.getWindowToken(), 0);
} }
方法三:
int flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
getWindow().addFlags(flags);
方法四:
在onclick事件下.以下方法可行.(如果是EditText失去焦點/得到焦點,沒有效果)
InputMethodManager im = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
im.hideSoftInputFromWindow(getCurrentFocus().getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
軟鍵盤界面按鈕功能設置方法
使用android:imeOptinos可對Android自帶的軟鍵盤進行一些界面上的設置:
android:imeOptions="flagNoExtractUi"/>
android:imeOptions="flagNoExtractUi" //使軟鍵盤不全屏顯示,只占用一部分屏幕
同時,這個屬性還能控件軟鍵盤右下角按鍵的顯示內容,默認情況下為回車鍵
android:imeOptions="actionNone" //輸入框右側不帶任何提示 android:imeOptions="actionGo" //右下角按鍵內容為'開始' android:imeOptions="actionSearch" //右下角按鍵為放大鏡圖片,搜索 android:imeOptions="actionSend" //右下角按鍵內容為'發送' android:imeOptions="actionNext" //右下角按鍵內容為'下一步' android:imeOptions="actionDone" //右下角按鍵內容為'完成'
這里寫圖片描述
這里寫圖片描述
同時,可能EditText添加相應的監聽器,捕捉用戶點擊了軟鍵盤右下角按鈕的監聽事件,以便進行處理。
editText.setOnEditorActionListener(new OnEditorActionListener() {
@Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
Toast.makeText(MainActivity.this, "響應了配置后的按鍵", Toast.LENGTH_SHORT).show(); return false;
}
});
踩過的坑
一、軟鍵盤無法頂起頁面
開發中有個需求是將頁面底部的一個按鈕頂起,但是開發時發現Android5.0以后的版本設置了adjustResize屬性后無法成功頂起。糾結了好久,最后在stackoverflow找到解決方案,那就是在根布局上加上fitsSystemWindow=”true”即可。
這里寫圖片描述
這里的fitsSystemWindow具體的作用就是你的**contentview是否忽略actionbar,title,屏幕的底部虛擬按鍵,將整個屏幕當作可用的空間。 **
正常情況,contentview可用的空間是去除了actionbar,title,底部按鍵的空間后剩余的可用區域;這個屬性設置為true,則忽略,false則不忽略
二、自定義軟鍵盤按鈕功能無效
在edittext上加入Android:imeOptions=”actionSearch”這個屬性沒響應,最后發現在2.3及以上版本不起作用,解決方案:加上
android:singleLine="true"
因為輸入法鍵盤右下角默認的回車鍵本來就是換行用的,當設置單行后,回車換行就失去作用了,這樣就可以設置為搜索、發送、go等等。