Android EditText关于imeOptions的设置和响应

v2-e7788a7ca065a05c0bcde20abe34e9f3_1440w.jpg

日常开发中,最绕不开的一个控件就是EditText,随之避免不了的则是对其软键盘事件的监听,随着需求的不同对用户输入的软键盘要求也不同,有的场景需要用户输入完毕后,有一个确认按钮,有的场景需要的是回车,有的场景需要用户输入后进入下一项或者搜索,所幸的是,大部分需求场景通过修改原生设置就可满足,只要极少情况下才需要去写自定义键盘。而关于EditText唤起的软键盘中回车的功能可以通过imeOptions的设定来进行相应的设置。

其使用方式仅通过在xml中声明即可:

<EditText
            ...
            android:imeOptions="actionSend"/>

常用属性

如果不特殊声明,右下角按键则为回车键。其常用属性及相应功能设置如下:

属性 右下角按键显示及常见应用场景
actionGo 右下角按键显示“开始”
actionSearch 右下角显示放大镜,对应搜索功能场景
actionSend 右下角按键内容为"发送",一般用于即时聊天页面
actionNext 右下角按键内容为“下一步”或者“下一项”,会跳到下一个EditText
actionDone 右下角按键内容为“完成”
actionNone 无任何提示
flagNoExtractUi 使软键盘不全屏显示,只占用一部分屏幕,右下角按键为默认回车键在指定imeOptions后,还要添加android:inputType="text"属性。

也可以通过代码去设置对应属性,如下:

editText.setInputType(EditorInfo.TYPE_CLASS_TEXT);
editText.setImeOptions(EditorInfo.IME_ACTION_...);

其属性与代码中设置的常量关系为:

属性 对应常量
actionGo EditorInfo.IME_ACTION_GO
actionSearch EditorInfo.IME_ACTION_SEARCH
actionSend EditorInfo.IME_ACTION_SEND
actionNext EditorInfo.IME_ACTION_NEXT
actionDone EditorInfo.IME_ACTION_DONE
actionNone EditorInfo.IME_ACTION_NONE
actionUnspecified(未指定) EditorInfo.IME_ACTION_UNSPECIFIED

监听

对应的EditText可以设置相应的监听,editText.setOnEditorActionListener,在监听的onEditorAction()中通过返回的actionId参数来判断触发的对应事件。例如以下示例:

xml中简单设置一个EditText:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <EditText
        android:id="@+id/edt_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:imeOptions="actionGo"
        android:inputType="text"/>
</RelativeLayout>

对应在Activity中对其进行事件监听:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    EditText mEdtView = findViewById(R.id.edt_view);
    mEdtView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            switch (actionId){
                case EditorInfo.IME_ACTION_DONE:
                    Toast.makeText(MainActivity.this, "IME_ACTION_DONE", Toast.LENGTH_SHORT).show();
                    break;
                case EditorInfo.IME_ACTION_GO:
                    Toast.makeText(MainActivity.this, "IME_ACTION_GO", Toast.LENGTH_SHORT).show();
                    break;
                case EditorInfo.IME_ACTION_NEXT:
                    Toast.makeText(MainActivity.this, "IME_ACTION_NEXT", Toast.LENGTH_SHORT).show();
                    break;
                case EditorInfo.IME_ACTION_NONE:
                    Toast.makeText(MainActivity.this, "IME_ACTION_NONE", Toast.LENGTH_SHORT).show();
                    break;
                case EditorInfo.IME_ACTION_PREVIOUS:
                    Toast.makeText(MainActivity.this, "IME_ACTION_PREVIOUS", Toast.LENGTH_SHORT).show();
                    break;
                case EditorInfo.IME_ACTION_SEARCH:
                    Toast.makeText(MainActivity.this, "IME_ACTION_SEARCH", Toast.LENGTH_SHORT).show();
                    break;
                case EditorInfo.IME_ACTION_SEND:
                    Toast.makeText(MainActivity.this, "IME_ACTION_SEND", Toast.LENGTH_SHORT).show();
                    break;
                case EditorInfo.IME_ACTION_UNSPECIFIED:
                    Toast.makeText(MainActivity.this, "IME_ACTION_UNSPECIFIED", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
            return true;
        }
    });
}

其对应效果为:

Edit-Text-Gif.gif

对应吐司也验证了我们代码的运行,我们再在xml中删除对应属性,用代码的形式声明试试。

xml中:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <EditText
        android:id="@+id/edt_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:inputType="text"/>
</RelativeLayout>

可见,其余无变动,对应activity的修改则是在设置监听前设置对应属性:

...
mEdtView.setImeOptions(EditorInfo.IME_ACTION_SEND);
...

其效果为:

Edit-Text-Gif2.gif

可见,代码中设置效果则一样,也许你会疑问,为什么点击右下角按键后还不能收起软键盘,系统中是没有这样主动行为的,需要我们自己来调用以下方法即可:

InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(context.getWindow().getDecorView().getWindowToken(), 0);

重复响应问题

这里需要注意的是,onEditorAction中,如果返回的是false,则onEditorAction中的代码可能会调用两次,原因不难理解,系统会首先判断用户实现的方法onEditorActionListener.onEditorAction(this, actionCode, null)的返回值,一旦返回true,会立即return,因此系统的处理被直接跳过。

设置无效问题

当设置了android:maxLines=“1” 属性时,有可能出现设置无效问题,这里要改为android:singleLine="true"此属性即可。当然,有可能个别的机型还有其他适配问题,比如三星等等,有遇见的朋友可以留言互相交流。

相关推荐

  1. qt 关于设置背景颜色,背景透明方法

    2024-02-17 13:30:03       18 阅读
  2. 关于分布式系统设计个人看法经验

    2024-02-17 13:30:03       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-17 13:30:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-17 13:30:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-02-17 13:30:03       82 阅读
  4. Python语言-面向对象

    2024-02-17 13:30:03       91 阅读

热门阅读

  1. 寒假作业2月13号

    2024-02-17 13:30:03       50 阅读
  2. 每日一个脚本之一键部署Docker

    2024-02-17 13:30:03       53 阅读
  3. 简单试验:用Excel进行爬虫

    2024-02-17 13:30:03       46 阅读
  4. Vue的双向绑定数据的原理

    2024-02-17 13:30:03       54 阅读
  5. 【Linux】指令 【scp】

    2024-02-17 13:30:03       48 阅读
  6. Matplotlib plt.plot数据可视化应用案例

    2024-02-17 13:30:03       53 阅读