zoukankan      html  css  js  c++  java
  • 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;
        }
    实现起来非常easy!只是当我把用户输入的字符串存储起来时候,问题就来了!

    原来这个用户输入的字符串须要存储在一段我们自己配置的nv里面,重要的是,分给我存储的字符串的空间仅仅有20个byte,没有错就是byte. 所以非常easy,输入的字符最多不能超过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 "";
                }

            }




  • 相关阅读:
    GridControl主从表设置
    Asp.net Ajax框架教程
    实现类似百度下拉框自动匹配功能
    将一个DataTable分解成多个DataTable
    找不到可安装的ISAM ,asp.net读取数据丢失,解决的一列里有字符与数字的
    StringCollection FAQ [C#, BCL]
    从枚举的初始化说起 [C#]
    当多态遇上数组 ... [C++] (Rewritten)
    我并不是不闻不问![C#]
    当多态遇上数组 ... [C++, C++/CLI, C#]
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/6912431.html
Copyright © 2011-2022 走看看