美文网首页工作
EditText的多行输入和回车键的监听

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

作者: Fritz_Xu | 来源:发表于2017-10-16 21:01 被阅读88次

    今天遇到个需求,需要 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,问题解决了。

    相关文章

      网友评论

        本文标题:EditText的多行输入和回车键的监听

        本文链接:https://www.haomeiwen.com/subject/iadluxtx.html