android 之EditText输入检测
最近开发一个功能的时候发生一个故事,其情节如下:
功能其实不复杂,其中需要一个EditText来获取用户输入的信息.于是,我做了一个Dialog来显示我的输入界面(代码如下):
mAlertDialog = new AlertDialog.Builder(this)//, android.R.style.Theme_Holo_Light .setIcon(R.drawable.ic_dialog_info_light) .setTitle(R.string.model_rename_device) .setView(createDialogView(deviceName)) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { //String deviceName = mDeviceNameView.getText().toString(); reset_success=false; reset_model_name(mDeviceNameView.getText().toString()); //finish(); } }) .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { //finish(); } }) .setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface arg0) { if(reset_success){ start_confir_ResetPhone(); }else{ finish(); } } }) .create(); mAlertDialog.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); mAlertDialog.show();
private View createDialogView(String deviceName) { final LayoutInflater layoutInflater = (LayoutInflater)this .getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = layoutInflater.inflate(R.layout.dialog_edittext, null); mDeviceNameView = (EditText) view.findViewById(R.id.edittext); mDeviceNameView.setFilters(new InputFilter[] { new Utf8ByteLengthFilter(MODEL_NAME_MAX_LENGTH_BYTES) }); mDeviceNameView.setText(deviceName); // set initial value before adding listener mDeviceNameView.addTextChangedListener(this); mDeviceNameView.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_DONE) { reset_model_name(v.getText().toString()); mAlertDialog.dismiss(); //finish(); return true; // action handled } else { //finish(); return false; // not handled } } }); mDeviceNameView.setSelection(mDeviceNameView.length()); return view; }实现起来很简单!不过当我把用户输入的字符串存储起来时候,问题就来了!
原来这个用户输入的字符串需要存储在一段我们自己配置的nv里面,重要的是,分给我存储的字符串的空间只有20个byte,没有错就是byte. 所以很简单,输入的字符最多不能超过20个字符,由于是byte类型,所以对于输入的字符必须做检测,其字符必须在一个byte取值空间(0-127)里面.实际上就是asic码.
所以需要对输入的字符检测.
为了能够实时检测EditText输入的字符你需要EditText.addTextChangedListener()来添加一个TextWatcher的检测器,并且实现其中的方法:
public void afterTextChanged(Editable s)
public void beforeTextChanged(CharSequence s, int start, int count, int after)
public void onTextChanged(CharSequence s, int start, int before, int count)
首当其冲想到的办法是在afterTextChanged方法里面判断当前输入的字符是否时正确的字符,如果不是就通过Editable s来更改:s.delete()来删除.或者直接使用这个EditText的去从新设置输入的字符:setText();
其实,这两个办法都不行,当快速输入不对的字符时候就会出现异常,很显然时同步的问题.
很快我给出来另个解决方法:在onTextChanged()里面检测是否有异常的字符,如果有则通过Handler发送消息的形式来处理.
public void onTextChanged(CharSequence s, int start, int before, int count) { for(int i=0; i < count; i++){ if(s.charAt(i+start) > 127 || s.charAt(i+start) < 0){ Message msg = mHandler.obtainMessage(handleMessage_detection_MG); msg.obj = s; mHandler.sendMessage(msg); break; } } //Log.d(DEBUG_STR,"onTextChanged str="+s.toString()+"start="+start+"; before="+before+"; count="+count); }
Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case handleMessage_detection_MG: InptText_Error_correction((CharSequence) msg.obj); break; case handleMessage_blue_name_MG: InptText_rename_blue((String) msg.obj); break; default: break; } } };
private void InptText_Error_correction(CharSequence chars){ if(chars != null){ StringBuilder str_b = new StringBuilder(chars); char temp; int start_indx = -1; for(int i = 0; i < str_b.length(); i++){ temp = str_b.charAt(i); if(temp > 127 || temp < 0){ if(start_indx < 0){ start_indx = i; } str_b.deleteCharAt(i); } } mDeviceNameView.setText(str_b.toString()); if(start_indx < 0){ start_indx = mDeviceNameView.length(); } mDeviceNameView.setSelection(start_indx); Toast.makeText(Rename_model_activity.this, getString(R.string.set_name_Error_Character_notice), Toast.LENGTH_SHORT).show(); } }
最后要说的是:对于输入字符的限制可以通过EditText.setFilters()来配置:
mDeviceNameView.setFilters(new InputFilter[] { new Utf8ByteLengthFilter(MODEL_NAME_MAX_LENGTH_BYTES) });
MODEL_NAME_MAX_LENGTH_BYTES时输入字符的最大长度,Utf8ByteLengthFilter是InputFilter的子类.这里就是对输入长度的适配. 其实你会很快发现!InputFilter就是一个对输入字符的检测器.所以对于输入字符错误检测其实不用那么麻烦,其实InputFilter完全可以解决.实现他的方法: public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)对于输入的错误字符,字节返回""就可以:
for (int i = start; i < end; i++) {
char c = source.charAt(i);
if(c > 127 || c < 0){
return "";
}
}
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。