对EditText拓展完成输入内容分隔处理

      今天没有时间看源码了。就写一篇今天的工作记录吧,为了解决一个小功能,就对Android的EditText作了功能上的拓展。


     首先说下遇到的需求,在EditText中对用户输入的内容进行一次“重新排版”,即没四个字符串分为一组,每一组用空格隔开:核心源码如下:

       

<span style="font-size:18px;">/**
	 * 文本改变监听
	 * @author sunny
	 *
	 */
	private class DidaTextWatcher implements TextWatcher{
        //定义一个变量用于记录字符串的变化,
        int tempCount;
        
		@Override
		public void beforeTextChanged(CharSequence s, int start, int count,
				int after) {
			// TODO Auto-generated method stub
		}
		@Override
		public void onTextChanged(CharSequence s, int start, int before,
				int count) {
			//统计个数
			int len = s.length();
			//设置输入最大长度,后期按需增加此功能
			if(len >= textMaxLength){
			//	return;
			}
			//如果包含空格,就清除
			char[] chars = s.toString().trim().replace(" ", "").toCharArray();
			len = chars.length;
			//每4个分组,加上空格合成新的字符串
			StringBuffer sb = new StringBuffer();
			//注意,一定要加上这一个判断,否则会陷入死循环,因为我们在这里改变了字符串s,这个事件会一直被监听到
			//所以,只有当我们输入的字符串不在改变的时候就不在监听到了
			if(len != tempCount){
			for(int i=0;i<len;i++){
				
               //如果是密码状态就替换字符串
				if(isPassword){
					if(chars[i]+"" != " "){
						chars[i] = '*';
					}
				}
				//如果分割的话,每次遍历到4的倍数就添加一个空格
					
				if(i % maxLength == 0 && i !=0){
					sb.append(delimiter);
					sb.append(chars[i]);
				}else{
					sb.append(chars[i]);
				}
				//改变需求,将所有字符替换成*号,表示输入的是密码
				
			}
			text = sb.toString();
			//获取改变之后字符串的长度
			tempCount = text.trim().replace(" ","").length();
                         //设置新的字符串到文本
                         editText.setText(sb.toString());
			}
			//设置光标的位置
			if(text !=null){
				editText.setSelection(text.length());
			}
		}</span>

             正如上面代码所示最关键的代码在于对EditText中用户输入的内容变化作出相应的处理,此处为了良好的通用性,我也开放了一些其他属性供用户自主选择,如下方法:

         

<span style="font-size:18px;">	/**
	 * 设置是否密码
	 * @param isPassword
	 */
	public void setIsPassword(boolean isPassword){
		this.isPassword = isPassword;
	}
	/**
	 * 设置允许输入的最大长度
	 * @param textMaxLength
	 */
	public void setTextMaxLength(Integer textMaxLength){
		this.textMaxLength = textMaxLength;
	}
	/**
	 * 设置分割符号,是空格还是"-"还是其他符号,默认的是空格
	 * @param delimiter
	 */
	public void setDelimiter(String delimiter) {
		this.delimiter = delimiter;
	}
	/**
	 * 设置分割时每组的字符数,默认的是4个
	 * @param maxLength
	 */
	public void setMaxLength(Integer maxLength){
		this.maxLength = maxLength;
	}
	/**
	 * 一次性设置分割
	 * @param isDivision  是否分割
	 * @param maxLength   分割的每组数目
	 * @param delimiter   分割符号
	 */
	public void setDivision(Integer maxLength,String delimiter){
		this.maxLength = maxLength;
		this.delimiter = delimiter;
	}</span>
           上面的代码正如大家所见,我提供了几个开放的属性让用户拥有更多的自主权,比如用户是否要将其输入的文本隐藏,即密码框,但是和EditText的密码框不一样哈!而且提供了分割的字符串数目。如果不需要分割,调用方法时传入一个“”参数就可以了。虽然如此,还不够完善,因为此类控件是直接继承EditText完成的,没有实现定制一个个性化的编辑框。还有点时间可以顺便写一个复合控件。接下来就将此类改变下让其继承LinearLayout类来定制个性化的EditText,还是另外开一个类来写吧。

        首先要明确一个概念,即复合控件和自定义视图是不一样的,前者是我们不需要去重写那些onMeasure()、onLayout()、onDraw()方法的。我们只需要继承一个写一个xml布局文件将已有的控件组合起来,然后编写一个类继承LinearLayou或其他容器类,进行填充即可,然后在该类里面也可以处理相应的想要拓展的功能。而后者是需要我们重写一系列方法,完全重绘一个视图的。下面我们基于复合视图来写一个个性化的EditText,首先是其xml布局文件:

        

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <TextView 
        android:id="@+id/text_edit"
        android:layout_width="50dip"
        android:layout_height="wrap_content"
        android:background="@drawable/text_edit"/>
    <EditText 
        android:id="@+id/dida_edit_text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/text_edit"
        android:background="@drawable/dida_edit_text"
        android:imeOptions="actionDone"
        android:hint="呵呵.."
     />
   
</RelativeLayout>
      布局很简单,TextView就用来提供文字和图片,EditText是我们的编辑框,然后相应的类代码:

       

public DidaEditTextfromLinearLayout(Context context,AttributeSet attrs){
		super(context,attrs);
		View v = LayoutInflater.from(getContext()).inflate(R.layout.dida_edittext, this,true);
		init();
	}
    在其构造方法中进行填充,为了省篇幅就不把所有的代码贴出来了,里面冗杂代码略多,讲主要的。
其次提供一个init()方法如下:

   

public void init(){
	 	watcher = new DidaTextWatcher();
	 	editText = (EditText) findViewById(R.id.dida_edit_text);
	 	textView = (TextView) findViewById(R.id.text_edit);
	 	//设置为密码输入,不过达不到我想要的结果,还是自己写一个了
//	 	DidaEditText.this.setInputType(0x81);
		//文本改变监听
		editText.addTextChangedListener(watcher);
		//焦点监听
		editText.setOnFocusChangeListener(new DivisionFocusChangeListener());
	}

         此外,我还提供了一个更换TextView背景图片的方法:

    

	/**
	 * 设置TextView背景图片,如果不设置就是我提供的原图片
	 * @param tempdrable  图片资源,参数形式为:R.drable.image_name
	 */
	public void setTextViewImage(int tempdrable){
		Resources resource = getResources();
		Drawable drable = resource.getDrawable(tempdrable);
		textView.setBackgroundDrawable(drable);
	}
        其实该方法就是将系统的方法封装了一下,如果还需要对EditText的背景图片进行设置也可以提供一个封装的方法。最后就是使用该控件了,使用者的布局文件如下:

      

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dip" >
        <TextView 
            android:id="@+id/linear_textv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="16.6dip"
            android:height="30dip"
            android:text="用户名:"/>
        <com.dida.widget.DidaEditTextfromLinearLayout
            android:id="@+id/et_linear"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" 
            android:layout_toRightOf="@id/linear_textv"
            />
    </RelativeLayout>

</LinearLayout>
      没啥好说的,要把布局彻底搞熟练才行,这里需要注意的就是引用复合控件类时,要写类全名,不然在反射创建该对象会出错。

      哦、忘记上效果图了啊。。用手机模拟的,怎么上效果图啊!鄙人愚昧,直接将我用PS做的效果图哪来填充好了:

       


        至此,今天的日志完毕。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值