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

今天遇到个需求,需要 EditText控件监听软键盘的回车按键,将用户写下的多行文本提交到服务器。
一开始以为是个简单的要求,不过由于对EditText内部机制的不了解,导致比预期花多了不少时间去完成,特此记录一下。
如果是对EditText内部机制不熟悉的人的话,一开始应该会写出类似我们下面的代码:

@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; } }); }

然而当我们运行上面的代码,输入一大串东西后就会发现:
EditText的多行输入和回车键的监听
文章图片
image.png
在xml设置的android:imeOptions="actionDone"怎么没有起到作用?怎么软键盘的回车按键还是个换行符号的?
通过查询各种资料,要让EditText的imeOptions配置生效就必须设置下面两个属性中的一个:
android:singleLine="true" android:inputType="text"

【EditText的多行输入和回车键的监听】只要你设置了上面的任意一个(inputType属性不一定是设置text类型的,不过也不是全部的inputType类型都可以,具体的请自己去尝试),都可以让imeOptions配置生效和完成软键盘的回车键监听。不过估计你也察觉到了,上面两个属性,只要有一个在xml里面设置了,那么EditText就失去换行的作用了!!!
解决的方法 由于需求是多行输入,无论是android:singleLine="true"还是android:inputType="text"都限制了只能单行,那么有什么方法可以突破text类型的单行限制吗?当然是有的,EditText继承TextView,查看下TextView的setSingleLine方法可以看到一个applySingleLine方法,里面可以看到一些有趣的代码:
EditText的多行输入和回车键的监听
文章图片
image.png
setMaxLines方法大家应该偶读很熟悉了,setHorizontallyScrolling方法还是第一次见到,点进去看下注解:
EditText的多行输入和回车键的监听
文章图片
image.png
好的,这样子大概就知道了这个方法是设置文本能否超过View的宽度,如果是false,那么文本宽度最多只能是View的宽度。
看到这里,笔者第一时间在xml里面做了下面的设置:

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

EditText editText = (EditText) findViewById(R.id.editText); editText.setHorizontallyScrolling(false); editText.setMaxLines(Integer.MAX_VALUE);

运行看下代码:
EditText的多行输入和回车键的监听
文章图片
show.gif ok,问题解决了。

    推荐阅读