欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android开发之自定义EditText实现保留两位小数(附EditText光标宽度、颜色、高度的设置)

程序员文章站 2022-07-15 09:59:30
...

 雪后初霁,天气很好。阳光暖暖的从窗户照射进来,一月又将结束。时间太匆匆。

作为一名程序员,姑且称作程序员吧(其实是代码的搬运工),不应该整天沉浸在代码中不能自拔,在代码的海洋里,想破了喉咙,挠秃了金顶。偶尔也需要站起身,伸伸懒腰泡杯茶,抬头挺胸走至窗前,看一看这冬日的雪景,赏一赏泊雪的腊梅。

 时令已将近立春,之前寒冷的天气想必不会再有了,也许春风将近。旧历的新年就要开始,未来藏着很多人的梦,不仅仅程

序员,还有千千万万生活不易的人。新的一年还需更加努力。正因为如此,偶尔还需要放慢脚步,欣赏欣赏这窗外的景色(其实

是泡杯咖啡,抽支烟,完了继续来加班)。

 废话少说,罗里吧嗦一大堆,一句有用的也没有。接下进入今天的正题。

 在Android开发中,我们经常需要用到EditText输入框。EditText的用法大家都知道,不用我在这班门弄斧了。但有时候,

项目里需要实现输入金额,并自动保留两位小数时,原生的EditText便不能满足我们的需求了,这个时候就需要我们对EditText

进行封装,自定义一个EditText实现我们的需求。直接上代码:

1、自定义ClearEditText类(可清空内容的ClearEditText,网上某未码友写的,出处已无可考,请见谅

package com.liuss.work.widget;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.animation.Animation;
import android.view.animation.CycleInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.EditText;

import com.liuss.work.R;

public class ClearEditText extends EditText implements OnFocusChangeListener, TextWatcher {

	/** 清空按钮的引用 */
	private Drawable mClearDrawable;
	
	/** 控件是否有焦点 */
	private boolean hasFocus;
	
	public ClearEditText(Context context) {
		this(context, null);
	}
	
	public ClearEditText(Context context, AttributeSet attrs) {
		//这里构造方法很重要,很多属性可以在XML里面定义
		this(context,attrs,android.R.attr.editTextStyle);
	}
	
	public ClearEditText(Context context, AttributeSet attrs,int defStyle) {
		super(context,attrs,defStyle);
		init();
	}
	
	private void init() {
		//获取EditText的DrawaleRight,假如没有设置我们就使用默认的图片
		mClearDrawable = getCompoundDrawables()[2];
		if (mClearDrawable == null) {
			mClearDrawable = getResources().getDrawable(R.mipmap.input_clear);
		}
		
		mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
		//默认设置隐藏图标
		setClearIconVisible(false);
		//设置焦点改变的监听
		setOnFocusChangeListener(this);
		//设置输入框里面内容发生改变的监听
		addTextChangedListener(this);		
	}
	
	/**
	 * 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件
	 * 当我们按下的位置 在 EditText的宽度 - 图标到控件右边的间距 - 图标的宽度 和
	 * EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向就没有考虑
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if(event.getAction() == MotionEvent.ACTION_UP) {
			if(getCompoundDrawables()[2] != null) {
				boolean touchable= event.getX() > (getWidth() - getTotalPaddingRight())
						&& (event.getX() < ((getWidth() - getPaddingRight())));
				if(touchable) {
					this.setText("");
				}
			}
		}
		return super.onTouchEvent(event);
	}
	
	/**
	 * 设置清除图标的显示与隐藏,调用setCompoundDrawables为DitText绘制上去
	 * @param visible
	 */
	protected void setClearIconVisible(boolean visible) {
		Drawable right = visible ? mClearDrawable : null;
		setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
	}

	/** 
     * 当输入框里面内容发生变化的时候回调的方法 
     */  
    @Override   
    public void onTextChanged(CharSequence s, int start, int count, int after) {
    	if(hasFocus) {
    		setClearIconVisible(s.length() > 0);
    	}
    }

	@Override
	public void afterTextChanged(Editable s) {
		
	}

	/**
	 * 当clearEditText焦点发生变化的时候,判断里面字符串长度设置清楚图标的显示与隐藏
	 */
	@Override
	public void onFocusChange(View v, boolean hasFocus) {
		this.hasFocus = hasFocus;
		if(hasFocus) {
			setClearIconVisible(getText().length() > 0);
		}else {
			setClearIconVisible(false);
		}
	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {
		
	}
	
	/**
	 * 设置晃动动画
	 */
	public void setShakeAnimation() {
		this.setAnimation(shakeAnimation(5));
	}
	
	/**
	 * 晃动动画
	 * @param counts 1秒钟晃动多少下
	 * @return
	 */
	public static Animation shakeAnimation(int counts) {
		Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
		translateAnimation.setInterpolator(new CycleInterpolator(counts));
		translateAnimation.setDuration(1000);
		return translateAnimation;
	}

}

:R.mipmap.input_clear为清空按钮图标

2、自定义MoneyEditText类继承ClearEditText类(如果不需要清除功能,也可以直接继承EditText

package com.liuss.work.widget;

import android.content.Context;
import android.util.AttributeSet;

public class MoneyEditText extends ClearEditText {

	public MoneyEditText(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int count, int after) {
		super.onTextChanged(s, start, count, after);

		if (s.toString().contains(".")) {
			if (s.length() - 1 - s.toString().indexOf(".") > 2) {
				s = s.toString().subSequence(0,
						s.toString().indexOf(".") + 3);
				this.setText(s);
				this.setSelection(s.length());
			}
		}

		if (s.toString().trim().substring(0).equals(".")) {
			s = "0" + s;
			this.setText(s);
			this.setSelection(2);
		}

		if (s.toString().startsWith("0")
				&& s.toString().trim().length() > 1) {
			if (!s.toString().substring(1, 2).equals(".")) {
				this.setText(s.subSequence(0, 1));
				this.setSelection(1);
				return;
			}
		}

	}

}
3、布局代码activity_test_money_edit.xml

<?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:gravity="center"
    android:orientation="vertical">

    <com.liuss.work.widget.MoneyEditText
        android:id="@+id/moneyEditText"
        android:layout_width="300dp"
        android:layout_height="50dp"
        android:background="@drawable/shanp_edit"
        android:hint="请输入金额"
        android:inputType="numberDecimal"
        android:maxLength="10"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:textCursorDrawable="@drawable/cursor_style"
        android:textSize="16sp" />

</LinearLayout>
案:布局中的关键属性 

//设置EditText背景边框

android:background="@drawable/shanp_edit"

//设置光标宽度、颜色、高度(顺便整理一下)

android:textCursorDrawable="@drawable/cursor_style"

//设置输入类型:numberDecimal小数点类型

android:inputType="numberDecimal"

shanp_edit.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <solid android:color="#00ffffff" />

    <stroke
        android:width="1px"
        android:color="#c7c7c7" />

    <corners android:radius="30dp" />

</shape>
cursor_style.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <!-- 光标宽度 -->
    <size
        android:width="2dp" />

    <!-- 光标颜色 -->
    <solid
        android:color="@color/colorPrimary" />

    <!-- 光标位置高度 -->
    <padding
        android:top="0sp"
        android:bottom="0sp" />
    
</shape>

重点代码:

    TextWatcher textWatcher = new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence sequence, int start, int before, int count) {
            if (sequence.toString().contains(".")) {
                if (sequence.length() - 1 - sequence.toString().indexOf(".") > 2) {
                    sequence = sequence.toString().subSequence(0,
                            sequence.toString().indexOf(".") + 3);
                    mEditText.setText(sequence);
                    mEditText.setSelection(sequence.length());
                }
            }

            if (sequence.toString().trim().substring(0).equals(".")) {
                sequence = "0" + sequence;
                mEditText.setText(sequence);
                mEditText.setSelection(2);
            }

            if (sequence.toString().startsWith("0")
                    && sequence.toString().trim().length() > 1) {
                if (!sequence.toString().substring(1, 2).equals(".")) {
                    mEditText.setText(sequence.subSequence(0, 1));
                    mEditText.setSelection(1);
                    return;
                }
            }
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    };

附(动态设置EditText中hint字体大小和text字体大小):

    TextWatcher textWatcher = new TextWatcher() {
        boolean hint;
        @Override
        public void onTextChanged(CharSequence sequence, int start, int before, int count) {
            if(sequence.length() == 0) {
                // no text, hint is visible
                hint = true;
                mEditText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
            } else {
                // no hint, text is visible
                hint = false;
                mEditText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 50);

            }
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    };
	
	附(动态设置EditText中hint字体大小和text字体大小):

效果图:

Android开发之自定义EditText实现保留两位小数(附EditText光标宽度、颜色、高度的设置)

至此总结完毕,附的图比较low,能看明白就好。