基本介绍

软键盘的显示原理
  软键盘其实是一个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>

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

  1. android软键盘的管理和属性的设置

    android:windowSoftInputMode activity主窗口与软键盘的交互模式,可以用来避免输入法面板遮挡问题,Android1.5后的一个新特性. 这个属性能影响两件事情: [一] ...

  2. ionic 项目中ios上遇到的软键盘输入法自动弹出的问题

    一.  安装插件 cordova plugin add ionic-plugin-keyboard 二. 软键盘显示监听 window.addEventListener('native.keyboar ...

  3. [问题]Android listView item edittext 不能调用软键盘输入法

    android listview item edittext not  softkeyboard edittext可以获取焦点, 可以触发事件, 但是就是不能调用输入法, 不知道为什么? 难道不能在i ...

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

    原文网址:http://www.2cto.com/kf/201505/401382.html 很多时候,我们在使用应用时,会出现输入法软键盘弹出的问题,通常情况下,我们默认会使用户点击返回键或者下一步 ...

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

    前言:   我们在android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的“GO”按键加载url页面:在点击搜索框的时候,点击右下角的sea ...

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

    前言:   我们在android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的“GO”按键加载url页面:在点击搜索框的时候,点击右下角的sea ...

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

    最近有类似需求,在csdn上刚好发现,粘贴过来,以防止忘记喽 前言:   我们在android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的“G ...

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

    软键盘显示的原理 软件盘的本质是什么?软键盘其实是一个Dialog.        InputMethodService为我们的输入法创建了一个Dialog,并且将该Dialog的Window的某些参 ...

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

    前言: 我们在Android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的“Go”按键加载url页面:在点击搜索框的时候,点击右下角的searc ...

随机推荐

  1. android 06

    1.android原理 菜单-->MainActivity-->onCreate-->setContentView(R.layout.item)-->layout(item.x ...

  2. Java学习----你可以告诉对象该怎么做(方法中传参)

    对象根据参数传递来的条件执行相应的功能. package org.demo.app2; public class App2 { public void print(String msg, int nu ...

  3. PHP 运算符 详解

    PHP 算数运算符 运算符 名称 例子 结果 + 加法 $x + $y $x 与 $y 求和 - 减法 $x - $y $x 与 $y 的差数 * 乘法 $x * $y $x 与 $y 的乘积 / 除 ...

  4. Swift互用性:与 C的API交互(Swift 2.0版)-b

    节包含内容: 基本数据类型(Primitive Types) 枚举(Enumerations) 指针(Pointer) 全局常量(Global Constants) 预处理指令(Preprocesso ...

  5. Swift互用性:与 Cocoa 数据类型共舞(Swift 2.0版)-b

    本节内容包括: 字符串(Strings) 数值(Numbers) 集合类(Collection Classes) 错误(Errors) Foundation数据类型(Foundation Data T ...

  6. 启动weblogic11g一直提示<141281> <unable to get file lock, will retry ...>

    一次非正常关闭weblogic之后,再次启动时启动不成功,一直提示:<141281> <unable to get file lock, will retry ...> 解决方 ...

  7. linux和windows下,C/C++的sleep函数

    简介: 函数名: sleep   功 能: 执行挂起一段时间   用 法: unsigned sleep(unsigned seconds);   在VC中使用带上头文件   #include < ...

  8. thickbox 关于动态生成 无法跳出弹出框的问题

    问题描述: 用jQuery动态生成thickbox的连接代码,发现没有效果. 原因: thickbox在页面加载后,会给a,input,area等绑定弹出事件. 通过tb_init(’a.thickb ...

  9. UVA138 Street Numbers(数论)

    题目链接. 题意: 找一个n,和一个m(m < n),求使得1~m的和等于m~n的和,找出10组m,n 分析: 列出来式子就是 m*(m+1)/2 = (n-m+1)*(m+n)/2 化简后为 ...

  10. (转载)PHP使用header函数设置HTTP头的示例方法表头

    (转载)http://justcoding.iteye.com/blog/601117/ 代码: //定义编码 header( 'Content-Type:text/html;charset=utf- ...