相信大家在项目中多多少少都用过EditText这个控件吧,但是大家是否熟悉它的监听呢?最近阿Q在使用它的监听的过程中就碰到了几个问题,在这里整理一下,供小伙伴们参考。
首先呢我们先声明一下EditText这个控件:
<EditText android:id="@+id/et_number" android:layout_width="50dp" android:layout_height="40dp" //控制长度 android:maxLength="5" android:textSize="18sp" //设置只允许输入数字 android:inputType="number" //可以输入小数 android:digits="0123456789."/>
在逻辑代码中添监听addTextChangedListener();
eNumber.addTextChangedListener(new TextWatcher(){ @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence s, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { } });
先说一下监听中的三个抽象函数,beforeTextChanged()为输入文字之后,还未显示在EditText上的操作;onTextChanged()为输入了文字,正在进行EditText显示的操作;afterTextChanged()为文字显示在EditText上的操作。大家应该注意的是如果在afterTextChanged()函数中去调用setText()方法,就会去重复调用其前两个方法,造成死循环,直到程序崩溃为止。所以我们在最后一个方法中要慎用setText(),所以我们只可将特殊情况的处理 用setText()来表示。
接下来给大家附上部分源码:
eNumber.addTextChangedListener(new TextWatcher(){ @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence s, int i, int i1, int i2) { //删除“.”后面超过2位后的数据 if (s.toString().contains(".")) { if (s.length() - 1 - s.toString().indexOf(".") > digits) { s = s.toString().subSequence(0, s.toString().indexOf(".") + digits+1); eNumber.setText(s); eNumber.setSelection(s.length()); //光标移到最后 } } //如果"."在起始位置,则起始位置自动补0 if (s.toString().trim().substring(0).equals(".")) { s = "0" + s; eNumber.setText(s); eNumber.setSelection(2); } //如果起始位置为0,且第二位跟的不是".",则无法后续输入 if (s.toString().startsWith("0") && s.toString().trim().length() > 1) { if (!s.toString().substring(1, 2).equals(".")) { eNumber.setText(s.subSequence(0, 1)); eNumber.setSelection(1); return; } } eNumber.setSelection(s.length()); //光标移到最后 } @Override public void afterTextChanged(Editable editable) { //变化后 String numberString = editable.toString(); if(numberString == null || "".equals(numberString)){ eNumber.setText("0"); }else{ Float num = Float.parseFloat(numberString); if(num<0){ eNumber.setText("0"); }else if(num>total){ eNumber.setText(total+""); } } } });
最后呢,给大家说一下RecyclerView中含有EditText复用的问题。在使用过程中,如果复用EditText的话,会出现输入数字错乱的问题,这时候我们需要加上监听的唯一标志,用于区分不同的监听,并且监听用完之后要记得移除监听。
//根据tag移除掉监听 if(editText.getTag() instanceof TextWatcher){ editText.removeTextChangedListener((TextWatcher) editText.getTag()); } TextWatcher textWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { //设置光标位置为最后 editText.setSelection(editText.getText().toString().length()); } }; editText.addTextChangedListener(textWatcher); editText.setTag(textWatcher);