工作

EditText的多行输入和回车键的监听

2017-10-16  本文已影响88人  Fritz_Xu

今天遇到个需求,需要 EditText控件监听软键盘的回车按键,将用户写下的多行文本提交到服务器。
一开始以为是个简单的要求,不过由于对EditText内部机制的不了解,导致比预期花多了不少时间去完成,特此记录一下。

如果是对EditText内部机制不熟悉的人的话,一开始应该会写出类似我们下面的代码:

<EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:background="@drawable/input_box"
        android:gravity="top|start"
        android:imeOptions="actionDone"
        android:padding="8dp" />
@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EditText editText = (EditText) findViewById(R.id.editText);
        editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    Toast.makeText(MainActivity.this, "Commit!", Toast.LENGTH_SHORT).show();
                    return true;
                }
                return false;
            }
        });
    }

然而当我们运行上面的代码,输入一大串东西后就会发现:

image.png

在xml设置的android:imeOptions="actionDone"怎么没有起到作用?怎么软键盘的回车按键还是个换行符号的?
通过查询各种资料,要让EditText的imeOptions配置生效就必须设置下面两个属性中的一个:

android:singleLine="true"
android:inputType="text"

只要你设置了上面的任意一个(inputType属性不一定是设置text类型的,不过也不是全部的inputType类型都可以,具体的请自己去尝试),都可以让imeOptions配置生效和完成软键盘的回车键监听。不过估计你也察觉到了,上面两个属性,只要有一个在xml里面设置了,那么EditText就失去换行的作用了!!!

解决的方法

由于需求是多行输入,无论是android:singleLine="true"还是android:inputType="text"都限制了只能单行,那么有什么方法可以突破text类型的单行限制吗?当然是有的,EditText继承TextView,查看下TextView的setSingleLine方法可以看到一个applySingleLine方法,里面可以看到一些有趣的代码:

image.png

setMaxLines方法大家应该偶读很熟悉了,setHorizontallyScrolling方法还是第一次见到,点进去看下注解:

image.png

好的,这样子大概就知道了这个方法是设置文本能否超过View的宽度,如果是false,那么文本宽度最多只能是View的宽度。
看到这里,笔者第一时间在xml里面做了下面的设置:

 <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:background="@drawable/input_box"
        android:gravity="top|start"
        android:imeOptions="actionDone"
        android:singleLine="true"
        android:maxLines="50"
        android:scrollHorizontally="false"
        android:padding="8dp" />

结果是不起作用的,猜测应该是TextView在初始化属性那边将android:singleLine属性放在了后面处理,那么在Java代码里面做处理会怎么样:

<EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:background="@drawable/input_box"
        android:gravity="top|start"
        android:imeOptions="actionDone"
        android:singleLine="true"
        android:padding="8dp" />
  EditText editText = (EditText) findViewById(R.id.editText);
  editText.setHorizontallyScrolling(false);
  editText.setMaxLines(Integer.MAX_VALUE);

运行看下代码:

show.gif

ok,问题解决了。

上一篇下一篇

猜你喜欢

热点阅读