这次来分享一个显示剩余输入字数功能的工具类CalculateUtil。由于这个功能非常简单,但若是想做得好也是需要一点技巧的,尤其是当你把它运用到项目里面的时候。这个功能是使用到TextWatcher这个类的,所以笔猪会以自己的理解去讲解一下TextWatcher这个类的使用。
首先我们来看一下要准备的材料:
如上图很简单,只需要一个给用户输入的EditText和放在一边显示剩余字数的TextView就可以了。
而这里,EditText最好也作一下用户输入字数的限制,虽然不能光靠xml来实现全部功能,但至少,用户输入的字数到达限定后,EditText不再接收后面的字数输入的功能是可以做到的。
下面给出我这个布局的xml,用maxLength就可以限制用户输入19个字后文本不再增加字数了:
<EditText
android:id="@+id/popuview_saysafe_edittext_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@null"
android:hint="自定义输入(不能多于30个字)"
android:maxLength="38"
android:maxLines="3"
android:paddingRight="4dp"
android:textColor="@color/discore_font_color"
android:textSize="@dimen/nomal_font" />
<TextView
android:id="@+id/popuview_saysafe_textview_inputlimitstr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/popuview_saysafe_edittext_input"
android:layout_alignRight="@+id/popuview_saysafe_edittext_input"
android:text="19"
android:textColor="@color/safety_bg_color"
android:textSize="@dimen/nomal_font" />
然后来了解一下TextWatcher:
它的使用是捆绑在一个EditText上的,如
editTextInput.addTextChangedListener(inputtextWatcher);
下面是对EditText加入文本监听:
private TextWatcher inputtextWatcher = new TextWatcher() {
//监听文本变化前
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
//监听文本变化中
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
//监听文本变化后
@Override
public void afterTextChanged(Editable s) {
try {
updateTextViewCount();
} catch (Exception e) {
e.printStackTrace();
}
}
};
从上面可以清楚的看到它的作用机理分别在于:文本变化前、变化中、和变化后的三种情况。而我们要做的则是在用户不断逐个逐个字输入的同时,每一次都监听文本的变化然后去改变显示剩余字数的TextView里面的数字。也就是说,显示剩余字数的主要功能会在 onTextChanged()这个方法里面进行。但要注意一下的是,当用户输入的时候,如果另一边要刷新显示剩余的字数的话,这样就很可能为出内存溢出的错误,因为在改变UI界面的同时,主线程要分别作用于用户输入的字数和监听文本里面变化后显示在TextView的剩余字数。不过这些都能客服,只要监听用户输入完后,停止TextWatcher的监听就好了,待下一次输入的时候再开启。大概主要逻辑就是这样,监听用户输入中→刷新TextView显示字数。就这么简单
接下来我们来看一下一张错误的效果图:
如图所示,这个是笔猪在看了很多网上相同功能的Demo后做出来的效果。之所以说是“错误”的,那是因为很多那些没做的完整的Demo它们的一个缺点就是字数统计所用到的字符编码这块没做好。因为他们没有判断当中英文混合输入的时候会出现的情况。
其实在刚才我所说的主要逻辑下,还应该有一个转化用户输入内容编码的机制。因为中文和英文输入所计算的字符是不同的(1个汉字为两个字符,一个字母为1个字符),如果这个字符处理不好,计算不统一,没有作好判断用户输入的究竟是汉字还是英文字母的话就会出现上图的这种情况:明明现显示还有剩余的字数却死活输入不了。所以当监听用户输入后还需要一个转化字符来计算显示的剩余字数的这样一个处理。
最后这个是本篇的本体:CalculateUtil.java
这个是笔猪自己写好封装起来的一个工具类,大家只需要复制粘贴成一个新的java文件放在自己项目里面的 Util(工具) 包即可使用,非常方便了。它解决了上面我所说的中英文混合输入出错的问题,对每一个输入的内容判断是中文还是英文,根据不同的字符而分开计算,这样就会避免有剩余字数但输入不了的情况了。
效果图:
CalculateUtil:
/**
* Created by Administrator on 2015/7/14.
* 显示剩余字数
*/
public class CalculateUtil {
private TextView textViewCount;
private int limitCount;
private EditText editTextInput;
/**
* @param textViewCount 剩余字数Textview
* @param limitCount 限制字数
* @param editTextInput 内容输入框
*/
public void updateParams(TextView textViewCount, int limitCount, EditText editTextInput) {
this.textViewCount = textViewCount;
this.limitCount = limitCount;
this.editTextInput = editTextInput;
this.editTextInput.addTextChangedListener(inputtextWatcher);
try {
updateTextViewCount();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 刷新控件
*/
private void updateTextViewCount() throws Exception {
String gbkText = editTextInput.getText().toString();
int remainCount = limitCount - gbkText.getBytes("GBK").length;
//剩余多少个汉字,如果是字符则不用除以2
textViewCount.setText(String.valueOf(remainCount / 2));
if (remainCount < 0) {
int deletIndex = editTextInput.getText().toString().length();
editTextInput.getEditableText().delete(deletIndex - 1, deletIndex);
}
}
private TextWatcher inputtextWatcher = new TextWatcher() {
//监听文本变化前
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
//监听文本变化中
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
//监听文本变化后
@Override
public void afterTextChanged(Editable s) {
try {
updateTextViewCount();
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
应用方法,如上面定义的:
private static final int LIMIT_COUNT = 38;
calculateUtilInput = new CalculateUtil();
calculateUtilInput.updateParams(limitcountinputTextView, LIMIT_COUNT, inputEditText);
注意一下,这个方法设定的限定字数,是计算字符的,也就是说比如限定字数是19个汉字的话,就应该是38个字符呢,好吧,这次就这么多,谢谢能来看的人呢~渣呢~