软键盘 输入法管理器 InputMethodManager

 基本介绍

软键盘的显示原理

  软键盘其实是一个Dialog。InputMethodService为我们的输入法创建了一个Dialog,并且对某些参数进行了设置,使之能够在底部或者全屏显示。当我们点击输入框时,系统会对当前的主窗口进行调整,以便留出相应的空间来显示该Dialog在底部,或者全屏。

控制活动主窗口调整方式   Android定义了一个属性windowSoftInputMode,用它可以让程序控制活动主窗口调整的方式。我们可以在配置文件AndroidManifet.xml中对Activity进行设置。这个属性的设置将会影响两件事情:      1>软键盘的状态——隐藏或显示。   2>活动的主窗口调整——是否减少活动主窗口大小以便腾出空间放软键盘或是否当活动窗口的部分被软键盘覆盖时它的内容的当前焦点是可见的。 该属性的设置必须是下面列表中的一个值,或一个“state…”值加一个“adjust…”值的组合。
  • "stateUnspecified": 软键盘的状态(隐藏或可见)没有被指定。系统将选择一个合适的状态,或依赖于主题的设置。这个是软键盘行为的默认设置。
  • "stateUnchanged":软键盘被保持上次的状态。当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示。
  • "stateHidden":当用户选择该Activity时,软键盘被隐藏。
  • "stateAlwaysHidden": 软键盘总是被隐藏的,即使当该Activity主窗口获取焦点时。
  • "stateVisible": 软键盘是可见的。
  • "stateAlwaysVisible": 当用户选择这个Activity时,软键盘是可见的。

  • "adjustUnspecified":这个是主窗口默认的行为设置,系统自动决定是采用平移模式还是压缩模式,决定因素在于内容是否可以滚动。
  • "adjustResize":压缩模式, 当软键盘弹出时,该Activity总是调整屏幕的大小以便留出软键盘的空间。
  • "adjustPan":平移模式,当输入框不会被遮挡时,该模式没有对布局进行调整;然而当输入框将要被遮挡时,窗口就会进行平移。也就是说,该模式始终是保持输入框为可见。该Activity主窗口并不调整屏幕的大小以便留出软键盘的空间,相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。

InputMethodManager 输入法管理器

一、常用方法:

获取输入法管理器

InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

显示输入法

imm.showSoftInput(View, InputMethodManager.SHOW_FORCED); 如此控件有需要,则显式要求软键盘区域向用户显示

切换输入法

imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED); 如果输入法在窗口上已经显示,则隐藏;如果隐藏,则显示输入法到窗口上

隐藏系统默认的输入法

imm.hideSoftInputFromWindow(MainActivity.this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

获取输入法打开的状态

boolean isOpen=imm.isActive();

二、让EditText默认不弹出软件键盘
  • 方法一:在AndroidMainfest.xml中设置此Activity的android:windowSoftInputMode="adjustUnspecified|stateHidden";或代码中设置getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)。
  • 方法二:使用EditText的clearFocus方法让EditText失去焦点。
  • 方法三:强制隐藏Android输入法窗口 imm.hideSoftInputFromWindow(et.getWindowToken(),0)。
  • 方法四:让EditText始终不弹出软键盘 et.setInputType(InputType.TYPE_NULL);或imm.hideSoftInputFromWindow(et.getApplicationWindowToken(), 0)。
三、带有EditText的控件不自动弹出键盘方法: 带有EditText控件的在第一次显示的时候会自动获得focus,并弹出键盘,如果不想自动弹出键盘,有两种方法: 1、在mainfest文件中把对应的activity设置,android:windowSoftInputMode="stateHidden" 或者android:windowSoftInputMode="stateUnchanged"。 2、可以在布局中放一个隐藏的TextView,然后在onCreate的时候requsetFocus。注意TextView不要设置Visiable=gone,否则会失效

系统API

常量值
  • HIDE_IMPLICIT_ONLY  hideSoftInputFromWindow(IBinder, int)中的标志,表示如果用户未显式地显示软键盘窗口,则隐藏窗口。
  • HIDE_NOT_ALWAYS  hideSoftInputFromWindow(IBinder, int)中的标志,表示软键盘窗口总是隐藏,除非开始时以SHOW_FORCED显示。
  • RESULT_HIDDEN  showSoftInput(View, int, ResultReceiver)和hideSoftInputFromWindow(IBinder, int, ResultReceiver)中ResultReceiver结果代码标志:软键盘窗口从显示切换到隐藏时的状态。
  • RESULT_SHOWN  showSoftInput(View, int, ResultReceiver)和hideSoftInputFromWindow(IBinder, int, ResultReceiver)中ResultReceiver结果代码标志:软键盘窗口从隐藏切换到显示时的状态。
  • RESULT_UNCHANGED_HIDDEN  showSoftInput(View, int, ResultReceiver)和hideSoftInputFromWindow(IBinder, int, ResultReceiver)中ResultReceiver结果代码标志:软键盘窗口不变保持隐藏时的状态。
  • RESULT_UNCHANGED_SHOWN  showSoftInput(View, int, ResultReceiver)和hideSoftInputFromWindow(IBinder, int, ResultReceiver)中ResultReceiver结果代码标志:软键盘窗口不变保持显示时的状态。
  • SHOW_FORCED  showSoftInput(View, int)中的标志,表示用户强制打开输入法(如长按菜单键),一直保持打开直至只有显式关闭。
  • SHOW_IMPLICIT  showSoftInput(View, int)中的标志,表示隐式显示输入窗口,非用户直接要求。窗口可能不显示。

公共方法
  • public void displayCompletions (View view, CompletionInfo[] completions)    输入法自动完成
  • public InputMethodSubtype getCurrentInputMethodSubtype ()    获取当前输入法类型
  • public List<InputMethodInfo> getEnabledInputMethodList ()    获取已启用输入法列表
  • public List<InputMethodSubtype> getEnabledInputMethodSubtypeList (InputMethodInfo imi, boolean allowsImplicitlySelectedSubtypes)
  • public List<InputMethodInfo> getInputMethodList ()    获取输入法列表
  • public Map<InputMethodInfo, List<InputMethodSubtype>> getShortcutInputMethodsAndSubtypes ()
  • public void hideSoftInputFromInputMethod (IBinder token, int flags)  关闭/隐藏输入法软键盘区域,用户不再看到或与其交互。只能由当前激活输入法调用,因需令牌(token)验证。参数,token 在输入法启动时提供令牌验证,验证后可对其进行操作。flags 提供额外的操作标志。当前可以为0或 HIDE_IMPLICIT_ONLY, HIDE_NOT_ALWAYS等位设置。
  • public boolean hideSoftInputFromWindow (IBinder windowToken, int flags), hideSoftInputFromWindow(IBinder, int, ResultReceiver)的无返回值版:从窗口上下文中确定当前接收输入的窗口,隐藏其输入法窗口。参数,windowToken 由窗口请求View.getWindowToken()返回得到的令牌(token)。flags 提供额外的操作标志。当前可以为0或 HIDE_IMPLICIT_ONLY位设置。
  • public boolean hideSoftInputFromWindow (IBinder windowToken, int flags, ResultReceiver resultReceiver),从窗口上下文中确定当前接收输入的窗口,要求隐藏其软键盘窗口。它可由用户调用并得到结果而不仅仅是显式要求输入法窗口隐藏。参数,windowToken 由窗口请求View.getWindowToken()返回得到的令牌(token)。flags 提供额外的操作标志。当前可以为0或 HIDE_IMPLICIT_ONLY位设置。resultReceiver 如不为空,当IME处理请求告诉你完成时调用。你收到的结果码可以是RESULT_UNCHANGED_SHOWN, RESULT_UNCHANGED_HIDDEN, RESULT_SHOWN, 或RESULT_HIDDEN。
  • public void hideStatusIcon (IBinder imeToken)    隐藏状态栏图标
  • public boolean isAcceptingText ()    当前服务视图接受全文编辑返回真。没有输入法联接为false,这时其只能处理原始按键事件。
  • public boolean isActive (View view)    视图为当前输入的激活视图时返回真。
  • public boolean isActive ()   输入法中的任意视图激活时返回真。
  • public boolean isFullscreenMode ()    判断相关输入法是否以全屏模式运行。全屏时,完全覆盖你的UI时,返回真,否则返回假。
  • public boolean isWatchingCursor (View view)    如当前输入法要看到输入编辑者的光标位置时返回真。
  • public void restartInput (View view)    如有输入法联接至视图,重启输入以显示新的内容。可在以下情况时调用此方法:视图的文字导致输入法外观变化或有按键输入流,如应用程序调用TextView.setText()时。参数,view 文字发生变化的视图。
  • public void sendAppPrivateCommand (View view, String action, Bundle data),对当前输入法调用 InputMethodSession.appPrivateCommand()。参数,view 可选的发送命令的视图,如你要发送命令而不考虑视图附加到输入法,此项可以为空。action 执行的命令名称。必须是作用域的名称,如前缀包名称,这样不同的开发者就不会创建冲突的命令。data 命令中包含的任何数据。
  • public boolean setCurrentInputMethodSubtype (InputMethodSubtype subtype)    此方法为3.0中新增的方法
  • public void setInputMethod (IBinder token, String id),强制切换到新输入法部件。只能由持有token的应用程序(application)或服务(service) 调用当前激活输入法。参数,token 在输入法启动时提供令牌验证,验证后可对其进行操作。id 切换到新输入法的唯一标识。
  • public void setInputMethodAndSubtype (IBinder token, String id, InputMethodSubtype subtype),强制切换到一个新的输入法和指定的类型。只能由持有token的应用程序(application)或服务(service) 调用当前激活输入法。参数,token 在输入法启动时提供令牌验证,验证后可对其进行操作。id 切换到新输入法的唯一标识。subtype 切换到新输入法的新类型。
  • public void showInputMethodAndSubtypeEnabler (String topId)    此方法为3.0中新增的方法
  • public void showInputMethodPicker ()    显示输入法菜单列表
  • public boolean showSoftInput (View view, int flags, ResultReceiver resultReceiver),如需要,显式要求当前输入法的软键盘区域向用户显示。当用户与视图交互,用户表示要开始执行输入操作时,可以调用此方法。参数,view 当前焦点视图,可接受软键盘输入。flags 提供额外的操作标志。当前可以是0或SHOW_IMPLICIT 位设置。resultReceiver 如不为空,当IME处理请求告诉你完成时调用。你收到的结果码可以是RESULT_UNCHANGED_SHOWN, RESULT_UNCHANGED_HIDDEN, RESULT_SHOWN, 或 RESULT_HIDDEN 。
  • public boolean showSoftInput (View view, int flags),showSoftInput(View, int, ResultReceiver)的无返回值版:如需要,显式要求当前输入法的软键盘区域向用户显示。参数,view 当前焦点视图,可接受软键盘输入。flags 提供额外的操作标志。当前可以是0或SHOW_IMPLICIT 位设置。
  • public void showSoftInputFromInputMethod (IBinder token, int flags),显示输入法的软键盘区域,这样用户可以到看到输入法窗口并能与其交互。只能由当前激活输入法调用,因需令牌(token)验证。参数,token 在输入法启动时提供令牌验证,验证后可对其进行操作。flags 提供额外的操作标志。可以是0或 SHOW_IMPLICIT, SHOW_FORCED位设置。
  • public void showStatusIcon (IBinder imeToken, String packageName, int iconId)    显示状态栏图标
  • public boolean switchToLastInputMethod (IBinder imeToken)
  • public void toggleSoftInput (int showFlags, int hideFlags)    切换软键盘
  • public void toggleSoftInputFromWindow (IBinder windowToken, int showFlags, int hideFlags),本方法切换输入法的窗口显示。如输入窗口已显示,它隐藏。如无输入窗口则显示。参数,windowToken 由窗口请求View.getWindowToken()返回得到的令牌(token)。showFlags 提供额外的操作标志。当前可以为0或 HIDE_IMPLICIT_ONLY位设置。hideFlags 提供额外的操作标志。可以是0或 HIDE_IMPLICIT_ONLY, HIDE_NOT_ALWAYS位设置。
  • public void updateCursor (View view, int left, int top, int right, int bottom),返回窗口的当前光标位置。
  • public void updateExtractedText (View view, int token, ExtractedText text)    当内容变化时文本编辑器调用此方法,通知其新提取文本。
  • public void updateSelection (View view, int selStart, int selEnd, int candidatesStart, int candidatesEnd),返回当前选择区域。

代码


public class MainActivity extends Activity implements OnClickListener, OnLayoutChangeListener {

    private LinearLayout root;

    private TextView tv;

    private ImageView iv;

    private EditText et;

    private InputMethodManager imm;

    private Rect firstRect;

    private final int ANIMATE_Y = 500;

    private final int ANIMATE_X = 200;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        root = (LinearLayout) findViewById(R.id.root);

        tv = (TextView) findViewById(R.id.tv);

        iv = (ImageView) findViewById(R.id.iv);

        et = (EditText) findViewById(R.id.et);

        imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

        Log.i("bqt", "onCreate++++++" + imm.isActive());//获取输入法打开的状态,false

        tv.setOnClickListener(this);

        //弹出窗口时自动让控件获取焦点,并弹出输入法。注意要在onCreate中法中设置,不能在onResume中设置。

        et.requestFocus();

        //开启一个定时器,500毫秒后执行一个定时任务

        new Timer().schedule(new TimerTask() {

            @Override

            public void run() {

                Log.i("bqt", "Timer++++++" + imm.isActive());//true

                //imm.showSoftInput(et,InputMethodManager.SHOW_FORCED);//如此控件有需要,则显式要求软键盘区域向用户显示

                //imm.hideSoftInputFromWindow(MainActivity.this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);//隐藏软键盘

                imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);//切换软键盘的显示与隐藏状态

            }

        }, 500);

        root.addOnLayoutChangeListener(this);

        root.post(new Runnable() {

            @Override

            public void run() {

                firstRect = new Rect();

                iv.getWindowVisibleDisplayFrame(firstRect);//封装可视大小到一个矩形中

            }

        });

    }

    //******************************************************************************************

    @Override

    public void onClick(View v) {

        switch (v.getId()) {

        case R.id.tv:

            imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);//切换软键盘的显示与隐藏

            Log.i("bqt", "hide++++++" + imm.isActive());//true,输入法虽然不显示了,但返回的仍然是true

            break;

        default:

            break;

        }

    }

    @Override

    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {

        Rect rect = new Rect();

        root.getWindowVisibleDisplayFrame(rect);

        if (firstRect != null) {

            //有时输入法弹出时会自动压缩或平移布局,此时这个值就要设置有一定阈值

            if (firstRect.height() - rect.height() > 0) softInputShowAnimate();

            else softInputHideAnimate();

        }

    }

    //******************************************************************************************

    /**

     * 键盘弹出时的动画

     */

    private void softInputShowAnimate() {

        if (iv.getTranslationX() != 0) return; //如果偏移过就不偏移了

        ObjectAnimator animatorX = ObjectAnimator.ofFloat(iv, "translationX", 0, ANIMATE_Y);//水平偏移

        ObjectAnimator animatorY = ObjectAnimator.ofFloat(iv, "translationY", -ANIMATE_X);//竖值偏移

        AnimatorSet animatorSet = new AnimatorSet();

        animatorSet.playTogether(animatorX, animatorY);

        animatorSet.setDuration(1000);

        animatorSet.start();

    }

    /**

     * 键盘隐藏时的动画

     */

    private void softInputHideAnimate() {

        if (iv.getTranslationX() == 0) return; //如果偏移过就不偏移了

        ObjectAnimator animatorX = ObjectAnimator.ofFloat(iv, "translationX", 0);//水平偏移

        ObjectAnimator animatorY = ObjectAnimator.ofFloat(iv, "translationY", firstRect.top);//竖值偏移,当然也可用ANIMATE_Y

        AnimatorSet animatorSet = new AnimatorSet();

        animatorSet.playTogether(animatorX, animatorY);

        animatorSet.setDuration(1000);

        animatorSet.start();

    }

}

布局


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/root"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >

    <TextView

        android:id="@+id/tv"

        android:layout_width="wrap_content"

        android:layout_height="300dp"

        android:background="#ff0"

        android:text="adjustPan 平移模式,当输入框不会被遮挡时,该模式没有对布局进行调整;然而当输入框将要被遮挡时,窗口就会进行平移。也就是说,该模式始终是保持输入框为可见。该Activity主窗口并不调整屏幕的大小以便留出软键盘的空间,相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。" />

    <ImageView

        android:id="@+id/iv"

        android:layout_width="wrap_content"

        android:layout_height="100dp"

        android:src="@drawable/ic_launcher" />

    <EditText

        android:id="@+id/et"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:background="#f0f"

        android:text="djustResize 压缩模式, 当软键盘弹出时,该Activity总是调整屏幕的大小以便留出软键盘的空间" />

</LinearLayout>

来自为知笔记(Wiz)

时间: 2024-08-13 05:50:26

软键盘 输入法管理器 InputMethodManager的相关文章

Android项目:输入法软键盘显示/隐藏的监听和控制,InputMethodManager用法研究

在项目开发中,用到编辑框的地方经常涉及到要监听或者控制软键盘的显示/隐藏状态.本以为这是很容易解决的一个小问题,没想到当初碰到这个问题才明白还得花点小心思才能整好.现将针对软键盘的显示/隐藏状态的监听/监控方法做一些总结,以备后用. 一.点击空白处隐藏软键盘 这是具有编辑框焦点的页面对输入法软键盘状态监听的一般需求和解决方法. 首先获得InputMethodManager:        InputMethodManager manager = (InputMethodManager) getS

【转】Android点击空白区域,隐藏输入法软键盘

原文网址:http://www.2cto.com/kf/201505/401382.html 很多时候,我们在使用应用时,会出现输入法软键盘弹出的问题,通常情况下,我们默认会使用户点击返回键或者下一步对软键盘进行隐藏.为了更好的体验,我们可以实现当用户使用完毕软键盘时.点击空白区域即可实现隐藏的功能.效果如图所示: 代码实现 代码块语法遵循标准markdown代码,例如: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

Android App监听软键盘按键的三种方式(转)

最近有类似需求,在csdn上刚好发现,粘贴过来,以防止忘记喽 前言: 我们在android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的“GO”按键加载url页面:在点击搜索框的时候,点击右下角的search符号键可以进行搜索:或者在全部数据输入完毕后,点击右下角的"done"就马上进行下一步操作. 效果图: function 1: 重写Activity的dispatchKeyEvent(KeyEvent event)方法,在其中

键盘-App监听软键盘按键的三种方式

前言: 我们在android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的“GO”按键加载url页面:在点击搜索框的时候,点击右下角的search符号键可以进行搜索:或者在全部数据输入完毕后,点击右下角的"done"就马上进行下一步操作. 效果图: function 1: 重写Activity的dispatchKeyEvent(KeyEvent event)方法,在其中监听KeyEventKey.KEYCODE_ENTER键(右下

Android App监听软键盘按键的三种方式

前言: 我们在android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的"GO"按键加载url页面:在点击搜索框的时候,点击右下角的search符号键可以进行搜索:或者在全部数据输入完毕后,点击右下角的"done"就马上进行下一步操作. 效果图: function 1: 重写Activity的dispatchKeyEvent(KeyEvent event)方法,在其中监听KeyEventKey.KEYCODE

彻底搞定Android开发中软键盘的常见问题

软键盘显示的原理 软件盘的本质是什么?软键盘其实是一个Dialog. InputMethodService为我们的输入法创建了一个Dialog,并且将该Dialog的Window的某些参数(如Gravity)进行了设置,使之能够在底部或者全屏显示.当我们点击输入框时,系统对活动主窗口进行调整,从而为输入法腾出相应的空间,然后将该Dialog显示在底部,或者全屏显示. 软键盘显示的调整 Android定义了一个属性,名字为windowSoftInputMode, 这个属性用于设置Activity主

Android修炼之道—获取软键盘的高度

自动弹出软键盘 editText = (EditText) findViewById(R.id.edit_text); editText.setFocusable(true); editText.setFocusableInTouchMode(true); editText.requestFocus(); InputMethodManager imm = imm.showSoftInput( edtsearch_title, InputMethodManager.RESULT_SHOWN); i

android 点击关闭软键盘

在项目中,editText获取焦点后,会自动弹出软键盘,关闭的时候一般需要按返回键或者点击软键盘上的按钮, 即使当前activity已经finish掉,软键盘依然存在,会影响用户的体验. 网上目前有很多很详细的办法,比如点击其他空白区域,软键盘就会消失之类的方法,我们项目中没有要求这个,要求的是只要 不遮挡其他操作,还有当前Activity关闭掉后软键盘消失就行, 今天给大家分享两个办法: //此方法,如果显示则隐藏,如果隐藏则显示 private void hintKbOne() { Inpu

Android:隐藏输入法软键盘

1.概述 1) 给LinearLayout 注册click 事件,点击后隐藏输入法软键盘.为什么要叫软键盘,很奇怪呢.通过Activity 的getSystem(Context.INPUT_METHOD_SERVICE) 获取到输入法的对象,接着把它隐藏掉. 2) EditText 输入的字符达到最大值时隐藏输入法软键盘.注册EditText 的TextWatcher 事件,通过判断输入的字符数达到最大长度时隐藏掉输入法软键盘. 2.Activity 后台代码 public class Edit