1. 程式人生 > >關於Android平臺顯示隱藏軟鍵盤輸入法的方法總結

關於Android平臺顯示隱藏軟鍵盤輸入法的方法總結

前言

在android開發中經常使用InputMethodManager來操作軟鍵盤的顯示隱藏,我們可以通過此類來控制顯示/隱藏軟鍵盤。

使用場景

在具有EditText的介面中,一般進入介面後,EditText控制元件會自動獲取焦點,並彈出輸入框,另外,當點選其它按鍵或者後臺返回資料時(如密碼驗證失敗),也可觸發EditText使其彈出軟鍵盤。

顯示/隱藏 軟鍵盤函式

彈出輸入框的方式有多種,但是大部分方式會有一些弊端,如單一的使用edittext.requestFocus( )函式,有可能在獲取焦點後,焦點又轉移到其他控制元件,此時不能保證軟鍵盤彈出。
在讀NumberPicker原始碼時,我發現瞭如下兩個方法:

    /**
     * Shows the soft input for its input text.
     */
    private void showSoftInput() {
        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
        if (inputMethodManager != null) {
            if (mHasSelectorWheel) {
                mInputText.setVisibility(View.VISIBLE);
            }
            mInputText.requestFocus();
            inputMethodManager.showSoftInput(mInputText, 0
); } } /** * Hides the soft input if it is active for the input text. */ private void hideSoftInput() { InputMethodManager inputMethodManager = InputMethodManager.peekInstance(); if (inputMethodManager != null && inputMethodManager.isActive(mInputText)) { inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0
); if (mHasSelectorWheel) { mInputText.setVisibility(View.INVISIBLE); } } }

這兩個方法分別用來顯示和隱藏軟鍵盤輸入法。但是由於InputMethodManager中的方法peekInstance( )是隱藏的:

    /**
     * Private optimization: retrieve the global InputMethodManager instance,
     * if it exists.
     * @hide
     */
    public static InputMethodManager peekInstance() {
        return sInstance;
    }

因此如果在專案中使用這兩個方法時,一般可採用反射的方式:

/**
     * Shows the soft input for its input text, by  reflection mechanism
     */
public  void showSoftKeyboard() {
          Object o = null;
         try{
             Class<?> threadClazz = Class.forName("android.view.inputmethod.InputMethodManager");

             Method method = threadClazz.getDeclaredMethod("peekInstance" );//return sInstance
             Method[] methods = threadClazz.getDeclaredMethods();

             method.setAccessible( true);
             o = method.invoke( null);
             if(o == null ){
                 return;
             }
             InputMethodManager inputMethodManager = (InputMethodManager)o;
             if (inputMethodManager != null) {
                edittext.requestFocus();
                 inputMethodManager.showSoftInput( edittext, 0);
             }
         } catch (Exception e){
         }
    }

    /**
     * Hides the soft input if it is active for the input text, by  reflection mechanism
     */
public void hideSoftKeyboard(){
         Object o = null;
         try{
             Class<?> threadClazz = Class.forName("android.view.inputmethod.InputMethodManager");

             Method method = threadClazz.getDeclaredMethod("peekInstance");//return sInstance
             Method[] methods = threadClazz.getDeclaredMethods();

             method.setAccessible( true);
             o = method.invoke( null);
             if(o == null ){
                 return;
             }
             InputMethodManager inputMethodManager = (InputMethodManager)o;
             if (inputMethodManager != null && inputMethodManager.isActive(edittext )) {
                 inputMethodManager.hideSoftInputFromWindow(edittext .getWindowToken(), 0);
             }
         } catch (Exception e){
         }
     }

以上兩個方法經測試後有效。

場景:

介面設定不自動彈出軟鍵盤,手動/後臺觸發

為了不使介面自動彈出軟鍵盤,比較常用的方式由兩種:

1.第一種方法:採用在manifest檔案中的某個Activity宣告處加上如下屬性:

    android:windowSoftInputMode="adjustUnspecified|stateHidden"

這種方式直接指明此activity介面的軟鍵盤初始狀態是隱藏的。

2.第二種方法:在佈局檔案中,為頂層的ViewGroup新增如下屬性:

    android:focusable= "true"
    android:focusableInTouchMode= "true"

這兩行程式碼將焦點置於佈局檔案的最外層ViewGroup上,EditText不會獲取焦點,因此在進入介面時,軟鍵盤不會自動彈出。

注意,這兩種方式下,要想再次彈出軟鍵盤,採用的方法略有不同。

在第一種情況下(即,設定Activity屬性),總結如下:
1.無論是否是在onCreate()中使用如下程式碼,均無法彈出軟鍵盤。

    edittext.setFocusable(true); 
    edittext.setFocusableInTouchMode(true); 
    edittext.requestFocus();

2.如果在onCreate()中使用如下程式碼,仍然無法彈出軟鍵盤。

    edittext.setFocusable(true);
    edittext.setFocusableInTouchMode(true);
    edittext.requestFocus();
    showSoftInput();

3.在onCreate()中可以使用此方法,彈出軟鍵盤。

    edittext.setFocusable(true); 
    edittext.setFocusableInTouchMode(true);
    edittext.requestFocus();
    edittext.postDelayed(new Runnable() {
        @Override
        public void run() {
            showSoftKeyboard();
        }
    }

在第二種情況下(即,設定Layout檔案中父控制元件獲取焦點),總結如下:
1.如果想在onCreate()中彈出軟鍵盤,只需要使用如下程式碼:

    edittext.setFocusable(true);
    edittext.setFocusableInTouchMode(true);
    edittext.requestFocus();

2.如果是在點選其它控制元件後想要觸發EditText彈出軟鍵盤,那麼需要新增主動顯示軟鍵盤的程式碼:

    edittext.setFocusable(true); 
    edittext.setFocusableInTouchMode(true);
    edittext.requestFocus();
    showSoftKeyboard();

需要新增showSoftKeyboard( )的原因是:當點選了其它按鍵後,焦點又回到了其它控制元件,因此需要強制新增showSoftKeyboard( )函式。