軟鍵盤相關

軟鍵盤顯示的原理

軟件盤的本質是什么?軟鍵盤其實是一個Dialog。 InputMethodService為我們的輸入法創(chuàng)建了一個Dialog,并且將該Dialog的Window的某些參數(shù)(如Gravity)進行了設置,使之能夠在底部或者全屏顯示。當我們點擊輸入框時,系統(tǒng)對活動主窗口進行調整,從而為輸入法騰出相應的空間,然后將該Dialog顯示在底部,或者全屏顯示。

軟鍵盤顯示的調整

android定義了一個屬性,名字為windowSoftInputMode, 這個屬性用于設置Activity主窗口與軟鍵盤的交互模式,用于避免軟鍵盤遮擋內容的問題。我們可以在AndroidManifet.xml中對Activity進行設置android:windowSoftInputMode=”stateUnchanged|adjustPan”。
該屬性可選的值有兩部分,一部分為軟鍵盤的狀態(tài)控制,控制軟鍵盤是隱藏還是顯示,另一部分是Activity窗口的調整,以便騰出空間展示軟鍵盤。
android:windowSoftInputMode的屬性設置必須是下面中的一個值,或一個”state”值加一個”adjust”值的組合,各個值之間用 | 分開。

  • stateUnspecified-未指定狀態(tài)**:當我們沒有設置android:windowSoftInputMode屬性的時候,軟件默認采用的就是這種交互方式,系統(tǒng)會根據(jù)界面采取相應的軟鍵盤的顯示模式。
  • stateUnchanged-不改變狀態(tài)**:當前界面的軟鍵盤狀態(tài),取決于上一個界面的軟鍵盤狀態(tài),無論是隱藏還是顯示。
  • stateHidden-隱藏狀態(tài)**:當設置該狀態(tài)時,軟鍵盤總是被隱藏,不管是否有輸入的需求。
  • stateAlwaysHidden-總是隱藏狀態(tài)**:當設置該狀態(tài)時,軟鍵盤總是被隱藏,和stateHidden不同的是,當我們跳轉到下個界面,如果下個頁面的軟鍵盤是顯示的,而我們再次回來的時候,軟鍵盤就會隱藏起來。
  • stateVisible-可見狀態(tài)**:當設置為這個狀態(tài)時,軟鍵盤總是可見的,即使在界面上沒有輸入框的情況下也可以強制彈出來出來。
  • stateAlwaysVisible-總是顯示狀態(tài)**:當設置為這個狀態(tài)時,軟鍵盤總是可見的,和stateVisible不同的是,當我們跳轉到下個界面,如果下個頁面軟鍵盤是隱藏的,而我們再次回來的時候,軟鍵盤就會顯示出來。
  • adjustUnspecified-未指定模式**:設置軟鍵盤與軟件的顯示內容之間的顯示關系。當你跟我們沒有設置這個值的時候,這個選項也是默認的設置模式。在這中情況下,系統(tǒng)會根據(jù)界面選擇不同的模式。
  • adjustResize-調整模式**:該模式下窗口總是調整屏幕的大小用以保證軟鍵盤的顯示空間;這個選項不能和adjustPan同時使用,如果這兩個屬性都沒有被設置,系統(tǒng)會根據(jù)窗口中的布局自動選擇其中一個。
  • adjustPan-默認模式**:該模式下通過不會調整來保證軟鍵盤的空間,而是采取了另外一種策略,系統(tǒng)會通過布局的移動,來保證用戶要進行輸入的輸入框肯定在用戶的視野范圍里面,從而讓用戶可以看到自己輸入的內容。

案例

沒有滾動布局xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

    <EditText
android:id="@+id/et1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框1" />

    <Button
android:id="@+id/btn1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="猴子搬來的救兵按鈕"
android:textSize="15sp" />

    <EditText
android:id="@+id/et2"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框2" />

    <EditText
android:id="@+id/et3"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框3" />

    <EditText
android:id="@+id/et4"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框4" />

    <EditText
android:id="@+id/et5"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框5" />

    <EditText
android:id="@+id/et6"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框6" />

    <EditText
android:id="@+id/et7"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框7" />

    <EditText
android:id="@+id/et8"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框8" />

    <EditText
android:id="@+id/et9"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框9" />

    <EditText
android:id="@+id/et10"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框10" />

    <EditText
android:id="@+id/et11"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框11" />

    <EditText
android:id="@+id/et12"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框12" />
</LinearLayout>

對于沒有滾動控件的布局來說,adjustPan就是默認的設置,比如我們案例應用中的文本輸入8,上面的文本輸入框123和按鈕都會被頂上去,且頁面布局不可以滾動。

這里寫圖片描述

有滾動布局xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

        <EditText
android:id="@+id/et1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框1" />

        <Button
android:id="@+id/btn1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="猴子搬來的救兵按鈕"
android:textSize="15sp" />

        <EditText
android:id="@+id/et2"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框2" />

        <EditText
android:id="@+id/et3"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框3" />

        <EditText
android:id="@+id/et4"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框4" />

        <EditText
android:id="@+id/et5"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框5" />

        <EditText
android:id="@+id/et6"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框6" />

        <EditText
android:id="@+id/et7"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框7" />

        <EditText
android:id="@+id/et8"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框8" />

        <EditText
android:id="@+id/et9"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框9" />

        <EditText
android:id="@+id/et10"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框10" />

        <EditText
android:id="@+id/et11"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框11" />

        <EditText
android:id="@+id/et12"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="文本輸入框12" />
    </LinearLayout>
   </ScrollView>

對于有滾動控件的布局,則是采用的adjustResize方式,比如我們案例應用中的文本輸入8,上面的文本輸入框123和按鈕都會被頂上去,可以通過滾動來查看被頂上去的內容。

這里寫圖片描述
這里寫圖片描述
   根據(jù)這一原理,我們就可以把開發(fā)中遇到的軟鍵盤遮擋頁面的問題,利用ScrollView當做根布局,讓系統(tǒng)采用adjustResize模式,很好地解決這一問題。

自動彈出軟鍵盤

有時候需要一進入Activity后就自動彈出軟鍵盤,可以通過設置一個時間函數(shù)來實現(xiàn),具體寫法如下:
方法一:

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后不希望系統(tǒng)自動彈出軟鍵盤,我們可以按照下面的方法來實現(xiàn):
方法一:
在AndroidMainfest.xml中選擇那個activity,設置windowSoftInputMode屬性為adjustUnspecified|stateHidden

<activity Android:name=".Main"
            Android:label="@string/app_name"
            Android:windowSoftInputMode="adjustUnspecified|stateHidden"
            Android:configChanges="orientation|keyboardHidden">
            <intent-filter>
                <action Android:name="android.intent.action.MAIN" />
                <category Android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
</activity>

方法二:
讓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);

動態(tài)關閉軟鍵盤

有時希望根據(jù)條件動態(tài)關閉軟鍵盤,我們可以使用InputMethodManager類,按照下面的方法來實現(xiàn):
方法一:

InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); //得到InputMethodManager的實例
if (imm.isActive()) {//如果開啟
    imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT,InputMethodManager.HIDE_NOT_ALWAYS);//關閉軟鍵盤,開啟方法相同,這個方法是切換開啟與關閉狀態(tài)的
}

方法二:

強制隱藏軟鍵盤
 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);

InputMethodManager的具體用法可以參考下面的鏈接:
http://www.apihome.cn/api/android/InputMethodManager.html

軟鍵盤界面按鈕功能設置方法

使用android:imeOptinos可對Android自帶的軟鍵盤進行一些界面上的設置:

<EditText  
    android:id="@+id/text1"  
    android:layout_width="150dip"  
    android:layout_height="wrap_content" 
    android:imeOptions="flagNoExtractUi"/> 
android:imeOptions="flagNoExtractUi"  //使軟鍵盤不全屏顯示,只占用一部分屏幕 

同時,這個屬性還能控件軟鍵盤右下角按鍵的顯示內容,默認情況下為回車鍵

android:imeOptions="actionNone"  //輸入框右側不帶任何提示 
android:imeOptions="actionGo"    //右下角按鍵內容為'開始' 
android:imeOptions="actionSearch"  //右下角按鍵為放大鏡圖片,搜索 
android:imeOptions="actionSend"    //右下角按鍵內容為'發(fā)送' 
android:imeOptions="actionNext"   //右下角按鍵內容為'下一步' 
android:imeOptions="actionDone"  //右下角按鍵內容為'完成'  
這里寫圖片描述
這里寫圖片描述

同時,可能EditText添加相應的監(jiān)聽器,捕捉用戶點擊了軟鍵盤右下角按鈕的監(jiān)聽事件,以便進行處理。

editText.setOnEditorActionListener(new OnEditorActionListener() { 
        @Override 
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 
            Toast.makeText(MainActivity.this, "響應了配置后的按鍵", Toast.LENGTH_SHORT).show(); 
            return false; 
        } 
}); 

踩過的坑

一、軟鍵盤無法頂起頁面

   開發(fā)中有個需求是將頁面底部的一個按鈕頂起,但是開發(fā)時發(fā)現(xiàn)Android5.0以后的版本設置了adjustResize屬性后無法成功頂起。糾結了好久,最后在stackoverflow找到解決方案,那就是在根布局上加上fitsSystemWindow=”true”即可。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
>
這里寫圖片描述

這里的fitsSystemWindow具體的作用就是你的contentview是否忽略actionbar,title,屏幕的底部虛擬按鍵,將整個屏幕當作可用的空間。
正常情況,contentview可用的空間是去除了actionbar,title,底部按鍵的空間后剩余的可用區(qū)域;這個屬性設置為true,則忽略,false則不忽略

二、自定義軟鍵盤按鈕功能無效

在edittext上加入Android:imeOptions=”actionSearch”這個屬性沒響應,最后發(fā)現(xiàn)在2.3及以上版本不起作用,解決方案:加上

android:singleLine="true"

因為輸入法鍵盤右下角默認的回車鍵本來就是換行用的,當設置單行后,回車換行就失去作用了,這樣就可以設置為搜索、發(fā)送、go等等。

轉自https://blog.csdn.net/mynameishuangshuai/article/details/51567357

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • //獲得軟鍵盤管理 InputMethodManager imm = (InputMethodManager)ge...
    link的勇氣閱讀 232評論 0 0
  • 博客搬遷到這里 http://blog.fdawei.club,歡迎訪問,大家一起學習交流。 Android開發(fā)中...
    猿某某閱讀 4,916評論 0 4
  • 開發(fā)中避免不了編輯文字,Android系統(tǒng)以為我們提供了軟鍵盤。世界開發(fā)中對于系統(tǒng)的軟鍵盤我們總想改點東西。今天就...
    mouekz閱讀 1,764評論 0 2
  • 《指紋》 文 | 子曰 它被打開出廠時的包裝有多久,那個指紋就存在了多久。她從未拿什么東西去擦拭過那枚指紋。除卻她...
    子曰漫曼閱讀 792評論 0 1
  • 利用碎片時間,今日(2018-11-4)臨完李陽冰《千字文》第二遍,進一步體會李陽冰篆書的嚴謹與放達的書風...
    田村散人閱讀 1,377評論 0 0

友情鏈接更多精彩內容