首页 > 代码库 > EditText字符限制-字节数限制-一次截取超过限制部分

EditText字符限制-字节数限制-一次截取超过限制部分

 

EditText字符限制-字节数限制-一次截取超过限制部分

 

一、需求描述:

       转载请注明出处:http://www.cnblogs.com/wangqx/p/6096272.html

对EditText字符个数限制,当用户输入字符串超长度过指定值时,不允许输入,并给出提示。

二、实现描述:

看了网上关于EditText字符串限制的一些例子,但都过于简单,不是想要的,故自己实现了下。

和网上例子功能对比:

1、此demo是对字符字节数的限制,无需区分是中文还是英文,相比对字符个数的限制, 对字节数限制更合理,因为同样字节数,中文和英文的字符串的个数是不一样的,需求中不会只要求对字符个数限制这么简单的

2、此demo截取超过的字符串部分时,是一次性截取,而其他大多例子中一个字符一个字符的截取(这样会多次触发afterTextChanged方法,如果给出吐司提示的话,将会多次弹出吐司,很不合理)

三、思路描述:

以在字符串中间插入字符串(插入后将会超出限制)的情况来归纳总结(其他情况如:在字符串前面插入,或者在字符串末尾插入,均可视为此种情况的特殊情况),思路很重要

1、获取改变前的字符串4、即下图中4部分

2、获取要插入的字符串、即下图中3部分

      3、依次将3中的字符串拼接到4后面,当字符串字节数超出限制时,将最后一次没有超出限制可以拼接的字符串的个数N记录下来(之所以记录个数而不是字节数,是为了截取,不可能把一个汉字分开,例如例子中一个汉字为3个字节,最大限制20个字节,就只能显示6个汉字,扔下2个字节就剩下吧,故截取的时候不能按字节截取,按字符个数截取)。此拼接只为暂时计算在字节数限制内总共可以容纳的字符串个数,

对应代码中if语句

     4、将下图3部分中超出限制的字符串删除,对应代码中s.delete操作

 

四、图示

其中、1为字符串改变前光标前的部分"你好",2为光标后的部分"美女",4为改变前的字符串"你好美女",3为要插入的字符串"我们都是",5为插入后没有处理的字符串"你好我们都是美女","我们都是"字符串将要插入在"你好"和"美女"之间,6/7/8/9分别对应"我"、"们"、"都"、"是" 这四个字,在拼接判断还可以插入多少字符串时用到

技术分享

五、代码实现

MainActivity.java

  1 package com.example.textwatcher;
  2 
  3 import android.app.Activity;
  4 import android.os.Bundle;
  5 import android.text.Editable;
  6 import android.text.TextWatcher;
  7 import android.widget.EditText;
  8 import android.widget.TextView;
  9 import android.widget.Toast;
 10 
 11 public class MainActivity extends Activity implements TextWatcher{
 12 
 13     private static final int MAX_LENGTH = 20;//最大字节数,不用区分是中文还是英文,字节数都是固定的,一般此值为255, 2^8 -1
 14     private EditText edittext;
 15     private TextView textview;
 16     private String temp = null;//临时变量
 17     private String name = null;//改变后的字符串
 18     private String frontString = null;//frontString是字符串 1
 19     private String middleString = null;//字符串3
 20     private String behindString = null;//字符串2
 21     private int editStart = 0;
 22     private int editEnd = 0;
 23     private int startPos = 0;//光标的位置,即1/2之间的位置
 24     private int endPos = 0;//改变文字后光标的位置
 25     @Override
 26     protected void onCreate(Bundle savedInstanceState) {
 27         super.onCreate(savedInstanceState);
 28         setContentView(R.layout.activity_main);
 29         edittext = (EditText) findViewById(R.id.et);
 30         textview = (TextView) findViewById(R.id.tv);
 31         edittext.addTextChangedListener(this);
 32     }
 33 
 34     @Override
 35     public void beforeTextChanged(CharSequence s, int start, int count,
 36             int after) {
 37         // TODO Auto-generated method stub
 38         startPos = start;//在字符串改变前保存光标的位置,即1、2之间的位置
 39         temp = s.toString();//保留字符串改变前的值 1+2、即4
 40         android.util.Log.i("wangqx", "beforeTextChanged temp="+temp);
 41         
 42         frontString = s.subSequence(0, startPos).toString();//frontString是字符串 1
 43         android.util.Log.i("wangqx", "frontString="+frontString);
 44         
 45     }
 46 
 47     @Override
 48     public void onTextChanged(CharSequence s, int start, int before, int count) {
 49         // TODO Auto-generated method stub
 50 
 51     }
 52 
 53     @Override
 54     public void afterTextChanged(Editable s) {
 55         // TODO Auto-generated method stub
 56         //此count和 beforeTextChanged方法中的count没有任何联系 
 57         int count = 0;//定义为局部变量,防止上次的值对其有影响(小编刚开始定义为了全局变量,结果引发的错误排查了很久)
 58         name = s.toString().trim();//主要是为了获取name的字节长度,为了调试用  、即5
 59         editEnd =  edittext.getSelectionEnd();
 60         behindString = name.substring(editEnd, name.length());//behindString是字符串2
 61         middleString = name.substring(startPos, editEnd);//middleString是字符串3
 62         android.util.Log.i("wangqx", "afterTextChanged temp="+temp);
 63         android.util.Log.i("wangqx", "afterTextChanged behindString="+behindString);
 64         android.util.Log.i("wangqx", "afterTextChanged middleString="+middleString);
 65         StringBuilder sb = new StringBuilder(temp);
 66         android.util.Log.i("wangqx", "name.getBytes().length="+name.getBytes().length);
 67         if(name.getBytes().length > MAX_LENGTH && middleString != null && middleString != ""){
 68             for(int i = 0;i < middleString.length();i++){
 69                 android.util.Log.i("wangqx", "middleString.subSequence(i, i+1)="+middleString.subSequence(i, i+1));
 70                 //依次将3中的字符串6、7、8、9拼接上去直到拼接后的字符串字节数大于最大值为止,将最多可以拼接的数赋值给count
 71                 //例如本例子中,小编在自己手机上打印到的每个汉字占3个字节(不是应该2个字节吗,很纳闷),"你好美女"共12字节,所以还可以拼接2个汉字
 72                 //即一共可以显示6个字,18个字节。最大是20个字节,如果是7个字的话,21个字节,超出范围了。故此时count为2
 73                 //在给count赋值时,一定要把count写在if语句里面,刚开始小编把count的赋值写在了for循环里面,if语句的下面了,最后发现当if语句不成立时
 74                 //count也有值,浪费了好久才找出问题
 75                 if(sb.append(middleString.subSequence(i, i+1)).toString().getBytes().length < MAX_LENGTH){
 76                     android.util.Log.i("wangqx", "i="+i);
 77                     android.util.Log.i("wangqx", "sb.toString()"+sb.toString());
 78                     count = i + 1;
 79                 }else{
 80                     break;//如果if语句不成立,则直接跳出for循环
 81                 }
 82             }
 83             
 84             android.util.Log.i("wangqx", "startPos="+startPos);
 85             android.util.Log.i("wangqx", "count="+count);
 86             android.util.Log.i("wangqx", "middleString.length()="+middleString.length());
 87             android.util.Log.i("wangqx", "middleString="+middleString);
 88             android.util.Log.i("wangqx", "s.toString().trim()="+s.toString().trim());
 89             android.util.Log.i("wangqx", "frontString="+frontString);
 90             android.util.Log.i("wangqx", "middleString.substring(0, count)="+middleString.substring(0, count)); //3中还可以拼接的字符串
 91             android.util.Log.i("wangqx", "behindString="+behindString);
 92             temp = new StringBuilder(frontString).append(middleString.substring(0, count)).append(behindString).toString();
 93             android.util.Log.i("wangqx", "before s.delete temp="+temp);
 94             Toast.makeText(this, "已超过字数限制", Toast.LENGTH_SHORT).show();
 95             
 96             ////delete掉3中字符串不可以拼接的部分
 97             //此时s字符串为  "你好我们都是美女" 
 98             //startPos + count 是1+3中可以拼接的字符串,即从"们"和"都"之间的位置开始,去掉"都是"这两个字符串
 99             //startPos值为2,count值为2,startPos + middleString.length()即为"是"后面的位置,删除"都是"
100             s.delete(startPos + count, startPos + middleString.length());
101             
102             android.util.Log.i("wangqx", "afters .delete temp="+temp);
103             android.util.Log.i("wangqx", "before setText###########");
104             //当执行s.delete时,字符串发生变变,会再次执行beforeTextChanged、afterTextChanged这些方法,只有执行完afterTextChanged方法后
105             //才会执行s.delete后面的方法,即textview.setText("1 ...);
106             //再一次执行afterTextChanged方法时,由于字符串长度已经没有超长,故会执行else中的方法,然后打印11 name= ,打印完后
107             //会继续执行s.delete下面的after setText###########,,然后再次打印11 name=
108             //textview.setText("1、内容:"+temp+" 字符数:"+temp.length()+" 字节数:"+temp.getBytes().length);
109             textview.setText(s.toString().trim());
110             android.util.Log.i("wangqx", "after setText###########");
111         }else{
112             textview.setText("2、内容:"+name+" 字符数:"+name.length()+" 字节数:"+name.getBytes().length);
113         }
114         android.util.Log.i("wangqx", "11 name="+name);
115         
116     }
117 }

 

 

activity_main.xml文件,只有两个空间,一个textview用来显示当前edittext中的内容(处理后,未超出限制的内容),editext用来输入字符,汉字,英文都可以

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     tools:context="${relativePackage}.${activityClass}" >
 6 
 7     <TextView
 8         android:id="@+id/tv"
 9         android:layout_width="wrap_content"
10         android:layout_height="wrap_content"
11         android:text="@string/hello_world" />
12 <EditText 
13     android:id="@+id/et"
14     android:layout_width="match_parent"
15     android:layout_height="wrap_content"
16     android:layout_below="@id/tv"/>
17 </RelativeLayout>

 

六、有疑问可以留言,欢迎探讨与指正 ,QQ群238696947

转载请注明出处:http://www.cnblogs.com/wangqx/p/6096272.html

 

EditText字符限制-字节数限制-一次截取超过限制部分