关于Android平台显示隐藏软键盘输入法的方法总结

Posted carbs_wang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于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( )函数。

以上是关于关于Android平台显示隐藏软键盘输入法的方法总结的主要内容,如果未能解决你的问题,请参考以下文章

android 软键盘的显示与隐藏问题的研究

Android软键盘的显示隐藏

如何在Android中判断软键盘是不是弹出或隐藏

Android——软键盘操作+fragment之间传递参数

关于Android中的软键盘

在片段替换上显示/隐藏 Android 软键盘