[置顶] Android EditText 千分位格式化 删除也要自动格式化 监听小数点让用户只能输入小数点后几位

android界面中edittext需要限制输入的数据的小数位数还有实时转换成千分位,千分位网上的没有解决方案,我写了一个,欢迎指教,关键是使用inputFilter过滤器,如下:

1.下述是转载的:最近项目需要输入价格,但是不想让用户在小数点后面输入太多,所以我封装了一个。当用户输入小数点的时候 监听小数点后面的位数,只要大于两位就立马删掉,封装好了,直接可以拿过来用!

public static void setPricePoint(final EditText editText) {
		editText.addTextChangedListener(new TextWatcher() {

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

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

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

			}

			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub
				
			}

		});

	}
我应用在自己的项目中是,小数点的位数是根据不同的商品来决定的,首先拿到这个商品决定的位数,然后再添加监听事件:
	final int digit = instrument.getDigits() + instrument.getExtraDigit();
		limitEditText.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				// boolean isAdd = DocCaptain.getInstance().isOrderTrade2Add();
				// refreshIDTLimitStopBasicPriceUI(false, isAdd);

				// 实现只能输入几位小数
				if (s.toString().contains(".")) {
					if (s.length() - 1 - s.toString().indexOf(".") > digit) {

						Toast to = Toast.makeText(getActivity(), "只能输入" + digit
								+ "位小数", Toast.LENGTH_LONG);
						to.show();

						s = s.toString().subSequence(0,
								s.toString().indexOf(".") + digit + 1);
						limitEditText.setText(s);
						limitEditText.setSelection(s.length());
					}
				}
				if (s.toString().trim().substring(0).equals(".")) {
					s = "0" + s;
					limitEditText.setText(s);
					limitEditText.setSelection(digit);
				}

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

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

			}

			@Override
			public void afterTextChanged(Editable s) {

			}

		});
===========================更新日期2015年10月26日15:30:54=============================
2.上述的代码的确是能限制小数点只能输入几位,但有一个很严重的异常是用户点击键盘的速度过快,就会导致程序卡住,无法再输入键盘上的数据,这完全是不能容忍的bug,所以只能找别的方法,后来百度了一下java早就提供了一个解决方法,就是使用过滤器inputFilter,绑定在输入框edittext上,实例如下:
final int digit = instrument.getDigits() + instrument.getExtraDigit();//小数位

		/**
		 * 设置小数位数控制
		 */
		InputFilter lengthfilter = new InputFilter() {
			@Override
			public CharSequence filter(CharSequence source, int start, int end,
					Spanned dest, int dstart, int dend) {
				// 删除等特殊字符,直接返回
				if ("".equals(source.toString())) {
					return null;
				}
				String dValue = dest.toString();
				System.out.println("有没有执行到这里");
				String[] splitArray = dValue.split("\\.");

				if (splitArray.length > 1) {
					System.out.println(splitArray[1] + "小数点分割之后的数值是多少");
					String dotValue = splitArray[1];
					int diff = dotValue.length() + 1 - digit;
					if (diff > 0) {
						System.out.println("返回的数据"
								+ source.subSequence(start, end - diff)
										.toString());
						return source.subSequence(start, end - diff);
					}
				}
				return null;
			}
		};
		limitEditText.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				//具体的业务逻辑
				
			}

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

			}

			@Override
			public void afterTextChanged(Editable s) {
			}

		});

		limitEditText.setFilters(new InputFilter[] { lengthfilter });//给输入框绑定inputfilter接口
我一开始遇到的问题是分割小数点,网上有一位前辈的代码是错误的,他是这样的:
String[] splitArray = dValue.split("\\.");直接拷贝下来会与错,建议还是重新写一下。

这个limitEditText.setFilters(new InputFilter[] { lengthfilter });可以添加多个过滤器,还可以实现:输入数据之后,转换成货币类型,例如输入3330000,可以转换成3,330,000.网络上没有解决方法,这是我自己写的欢迎拍砖,代码如下:
/**
		 * 设置转换成千分符 :source 新输入的字符串 start 新输入的字符串起始下标,一般为0 end
		 * 新输入的字符串终点下标,一般为source长度-1 dest 输入之前文本框内容 dstart 原内容起始坐标,一般为0 dend
		 * 原内容终点坐标,一般为dest长度-1
		 */
		InputFilter lengthfilter2 = new InputFilter() {
			@Override
			public CharSequence filter(CharSequence source, int start, int end,
					Spanned dest, int dstart, int dend) {
				// 删除等特殊字符,直接返回
				if ("".equals(source.toString())) {
					return null;
				}

				String dValue = dest.toString();
				dValue = dValue.replace(",", "");

				if (!dValue.equals("") && dValue.length() > 2
						&& !dValue.equals(".")) {

					String newValue = dValue + source;//避免自定义键盘上的:20,000逗号引发string转换错误
<span style="white-space:pre">					</span>newValue = newValue.toString();
<span style="white-space:pre">					</span>newValue = newValue.replace(",", "");
					double amount = Double.parseDouble(newValue);
					String amountStr = DecimalUtil.formatAmount(amount);

					amountEditText.setText("");
<span style="white-space:pre">					</span>amountEditText.setText(amountStr);
<span style="white-space:pre">					</span>amountEditText.setSelection(amountStr.length());

					System.out.println(amountStr + "看看转换后的数据" + "转换成功了的");

					return amountStr;
				} else {
					return null;
				}


			}
		};

		amountEditText.setFilters(new InputFilter[] { lengthfilter2 });

        主要思想是:当用户输入第4个数字的时候,进入if语句进行判断,取得edittext输入的一串数字,进行千分符转换,此时必须要将edittext设为空,再设置新值,否则会出现数据重复的意外bug,当输入第5位的时候,因为edittext的数据此时为3,000,000,无法不是字符串,需要将“,”逗号替换成空,然后重新判断,这样就可以实现限制edittext输入的数据为千分位。
===========================更新时间2015年10月27日09:01:58=========上述控制千分位的代码还可以添加只能输入15位,修改上述过滤器代码如下============
/**
		 * 设置转换成千分符 :source 新输入的字符串 start 新输入的字符串起始下标,一般为0 end
		 * 新输入的字符串终点下标,一般为source长度-1 dest 输入之前文本框内容 dstart 原内容起始坐标,一般为0 dend
		 * 原内容终点坐标,一般为dest长度-1
		 */
		InputFilter lengthfilter2 = new InputFilter() {
			@Override
			public CharSequence filter(CharSequence source, int start, int end,
					Spanned dest, int dstart, int dend) {
				// 删除等特殊字符,直接返回
				if ("".equals(source.toString())) {
					return null;
				}

				String dValue = dest.toString();
				dValue = dValue.replace(",", "");

				if (!dValue.equals("") && dValue.length() > 2
						&& !dValue.equals(".") && dValue.length() < 14) {

					String newValue = dValue + source;
                                        newValue = newValue.toString();
                                    newValue = newValue.replace(",", "");
					double amount = Double.parseDouble(newValue);
					String amountStr = DecimalUtil.formatAmount(amount);

					amountEditText.setText("");
amountEditText.setText(amountStr);
				amountEditText.setSelection(amountStr.length());

					System.out.println(amountStr + "看看转换后的数据" + "转换成功了的");

					return amountStr;
				} else if (!dValue.equals("") && dValue.length() >= 14//当已经15位的时候,返回为空
						&& !dValue.equals(".")) {

					return "";
				} else {
					return null;
				}


			}
		};
===========================更新日期,2015年12月16日13:40:27,===============================
1.当从xml设置edittext设置最多只能输入15位的时候,当java代码中设置了过滤器,就不会起作用,记录一下。
2.增加限制edittext,输入的小数:整数不能超过几位,小数限制几位数,如下代码:其实原理就是计算输入的数据大于某个数据,就不能输入。如下代码:
	/**
		 * 2015年10月27日09:58:32:给限价、停损添加小数位控制
		 */
		final int digit = instrument.getDigits() + instrument.getExtraDigit();
		/**
		 * 2015年12月16日13:36:52:控制整数位的位数
		 */
		final int digitInteger = 9999;

		/**
		 * 设置小数位数控制
		 */
		InputFilter lengthfilter = new InputFilter() {
			@Override
			public CharSequence filter(CharSequence source, int start, int end,
					Spanned dest, int dstart, int dend) {
				// 删除等特殊字符,直接返回
				if ("".equals(source.toString())) {
					return null;
				}
				String dValue = dest.toString();
				String[] splitArray = dValue.split("\\.");

				// 控制限价等价格的整数位的位数,逻辑是如果输入的数字大于设定的数据就提示
				double dold = Double.parseDouble(dValue + source.toString());
				if (dold > digitInteger) {
					Toast.makeText(getActivity(), "輸入的金額不能大於10位",
							Toast.LENGTH_SHORT).show();
					return dest.subSequence(dstart, dend);
				}

				// 控制小数位只能对应的商品位数
				if (splitArray.length > 1) {
					String dotValue = splitArray[1];
					int diff = dotValue.length() + 1 - digit;
					if (diff > 0) {
						return source.subSequence(start, end - diff);
					}
				}

				// else {
				//
				// String sIntegValue = splitArray[0];
				//
				// int diff = sIntegValue.length() - digitInteger;
				// if (diff > 0) {
				// return source.subSequence(start, end - diff);
				// }
				// }
				return null;
			}
		};

		/**
		 * 只能输入货币对对应的小数位数
		 */
		limitEditText.setFilters(new InputFilter[] { lengthfilter });

=======================分割线,更新日期2015年12月21日15:02:25===增加点击删除按钮,也要对原先的edittext进行千分位处理============================
完整的千分位增加删除之后的千分位格式化过滤器,直接上代码:
</pre>/**<span style="white-space:pre">		</span> * 设置转换成千分符 :source 新输入的字符串 start 新输入的字符串起始下标,一般为0 end<span style="white-space:pre">		</span> * 新输入的字符串终点下标,一般为source长度-1 dest 输入之前文本框内容 dstart 原内容起始坐标,一般为0 dend<span style="white-space:pre">		</span> * 原内容终点坐标,一般为dest长度-1<span style="white-space:pre">		</span> */<span style="white-space:pre">		</span>InputFilter lengthfilter2 = new InputFilter() {<span style="white-space:pre">			</span>@Override<span style="white-space:pre">			</span>public CharSequence filter(CharSequence source, int start, int end,<span style="white-space:pre">					</span>Spanned dest, int dstart, int dend) {<span style="white-space:pre">				</span>// 删除等特殊字符,直接返回<span style="white-space:pre">				</span>if ("".equals(source.toString())) {<span style="white-space:pre">					</span>return null;<span style="white-space:pre">				</span>}<span style="white-space:pre">				</span>String dValue = dest.toString();<span style="white-space:pre">				</span>dValue = dValue.replace(",", "");<span style="white-space:pre">				</span>String sValue = source.toString();<span style="white-space:pre">				</span>System.out.println(sValue + "========");<span style="white-space:pre">				</span>// 点击删除等特殊字符,直接返回<span style="white-space:pre">				</span>if ("".equals(sValue) && !"".equals(dValue)) {<span style="white-space:pre">					</span>String newValue = dValue.substring(0, dValue.length() - 1);<span style="white-space:pre">					</span>// 当删除全部的时候,已经是空,返回null<span style="white-space:pre">					</span>if (!newValue.equals("")) {<span style="white-space:pre">						</span>newValue = newValue.toString();<span style="white-space:pre">						</span>newValue = newValue.replace(",", "");<span style="white-space:pre">						</span>double amount = Double.parseDouble(newValue);<span style="white-space:pre">						</span>String amountStr = DecimalUtil.formatAmount(amount);<span style="white-space:pre">						</span>amountEditText.setText("");<span style="white-space:pre">						</span>amountEditText.setText(amountStr);<span style="white-space:pre">						</span>amountEditText.setSelection(amountStr.length());// 修改光标位置为最后面<span style="white-space:pre">						</span>return amountStr;<span style="white-space:pre">					</span>} else {<span style="white-space:pre">						</span>return null;<span style="white-space:pre">					</span>}<span style="white-space:pre">				</span>}<span style="white-space:pre">				</span>// String dValue = dest.toString();<span style="white-space:pre">				</span>// dValue = dValue.replace(",", "");<span style="white-space:pre">				</span>// String sValue = source.toString();<span style="white-space:pre">				</span>if (!dValue.equals("") && dValue.length() > 2<span style="white-space:pre">						</span>&& !dValue.equals(".") && dValue.length() < 7) {<span style="white-space:pre">					</span>String newValue = dValue + source;<span style="white-space:pre">					</span>newValue = newValue.toString();<span style="white-space:pre">					</span>newValue = newValue.replace(",", "");<span style="white-space:pre">					</span>double amount = Double.parseDouble(newValue);<span style="white-space:pre">					</span>String amountStr = DecimalUtil.formatAmount(amount);<span style="white-space:pre">					</span>amountEditText.setText("");<span style="white-space:pre">					</span>amountEditText.setText(amountStr);<span style="white-space:pre">					</span>amountEditText.setSelection(amountStr.length());// 修改光标位置为最后面<span style="white-space:pre">					</span>return amountStr;<span style="white-space:pre">				</span>} else if (!dValue.equals("") && dValue.length() >= 7<span style="white-space:pre">						</span>&& !dValue.equals(".")) {<span style="white-space:pre">					</span>Toast to = Toast.makeText(getActivity(), "只能輸入7位整數",<span style="white-space:pre">							</span>Toast.LENGTH_SHORT);<span style="white-space:pre">					</span>to.show();<span style="white-space:pre">					</span>return "";<span style="white-space:pre">				</span>} else if (sValue.equals(selfdig20) || sValue.equals(selfdig50)<span style="white-space:pre">						</span>|| sValue.equals(selfdig100)) {<span style="white-space:pre">					</span>// 当用户点击自定义金额时,清楚之前的数据,直接显示自定义金额<span style="white-space:pre">					</span>return sValue;<span style="white-space:pre">				</span>} else {<span style="white-space:pre">					</span>return null;<span style="white-space:pre">				</span>}<span style="white-space:pre">			</span>}<span style="white-space:pre">		</span>};<span style="white-space:pre">		</span>amountEditText.setFilters(new InputFilter[] { lengthfilter2 });</div><div>          2.自定义键盘对于删除按键的监听,需要特别处理,这里就是解决每次点击删除按钮,然后重新对edittext的内容重新千分位处理的动作。如下代码:<pre name="code" class="java">package client.verbank.mtp.allone.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.Keyboard.Key;
import android.inputmethodservice.KeyboardView;
import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
import android.os.Build;
import android.os.SystemClock;
import android.text.Editable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.ActionMode;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.PopupWindow.OnDismissListener;
import client.verbank.mtp.allone.R;
import client.verbank.mtp.allone.consts.ISystemCommData;

/**
 * 数字键盘


public class MyKeyboardDigitalCloseTrade extends EditText implements
		OnKeyboardActionListener, ISystemCommData {

	private Keyboard k1;// 字母键盘
	private Keyboard k2;// 标点符号键盘
	private Keyboard k3;// 数字键盘
	public boolean isnun = false;// 是否标点符号键盘
	public boolean isupper = false;// 是否大写

	private KeyboardView mKeyboardView;
	private Keyboard mKeyboard;

	private Window mWindow;
	private View mDecorView;
	private View mContentView;

	private PopupWindow mKeyboardWindow;

	private boolean needcustomkeyboard = true; // 是否启用自定义键盘
	private boolean randomkeys = false; // 数字按键是否随机

	private int scrolldis = 0; // 输入框在键盘被弹出时,要被推上去的距离

	public static int screenw = -1;// 未知宽高
	public static int screenh = -1;
	public static int screenh_nonavbar = -1; // 不包含导航栏的高度
	public static int real_scontenth = -1; // 实际内容高度, 计算公式:屏幕高度-导航栏高度-电量栏高度

	public static float density = 1.0f;
	public static int densityDpi = 160;

	// 接收用户在系统设定界面的自定义金额
	String selfdig20 = "200,000";
	String orgindi20 = "200,000";
	// 接收用户在系统设定界面的自定义金额
	String selfdig50 = "500,000";
	String orgindi50 = "500,000";
	// 接收用户在系统设定界面的自定义金额
	String selfdig100 = "1,000,000";
	String orgindi100 = "1,000,000";

	/**
	 * @param context
	 * 
	 * @param attrs
	 */
	public MyKeyboardDigitalCloseTrade(Context context, AttributeSet attrs) {
		super(context, attrs);
		initAttributes(context);
		initKeyboard(context, attrs);

		// TODO Auto-generated constructor stub
	}

	/**
	 * @param context
	 * @param attrs
	 * @param defStyle
	 */
	public MyKeyboardDigitalCloseTrade(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);

		selfdig20 = SharepreferencesUtilSystemSettings.getValue(getContext(),
				System_key_SelfAmout2, "200,000");
		selfdig50 = SharepreferencesUtilSystemSettings.getValue(getContext(),
				System_key_SelfAmout5, "500,000");
		selfdig100 = SharepreferencesUtilSystemSettings.getValue(getContext(),
				System_key_SelfAmout10, "1,000,000");
		initAttributes(context);
		initKeyboard(context, attrs);
		// TODO Auto-generated constructor stub
	}

	private void initKeyboard(Context context, AttributeSet attrs) {
		selfdig20 = SharepreferencesUtilSystemSettings.getValue(getContext(),
				System_key_SelfAmout2, "200,000");
		selfdig50 = SharepreferencesUtilSystemSettings.getValue(getContext(),
				System_key_SelfAmout5, "500,000");
		selfdig100 = SharepreferencesUtilSystemSettings.getValue(getContext(),
				System_key_SelfAmout10, "1,000,000");
		TypedArray a = context.obtainStyledAttributes(attrs,
				R.styleable.keyboard);

		if (a.hasValue(R.styleable.keyboard_xml)) {
			needcustomkeyboard = true;

			int xmlid = a.getResourceId(R.styleable.keyboard_xml, 0);

			mKeyboard = new Keyboard(context, xmlid);

			mKeyboardView = (KeyboardView) LayoutInflater.from(context)
					.inflate(R.layout.mykeyboardviewdigit, null);
			if (a.hasValue(R.styleable.keyboard_randomkeys)) {
				boolean random = a.getBoolean(R.styleable.keyboard_randomkeys,
						false);
				randomkeys = random;

				if (random) {
					randomdigkey(mKeyboard);
				}
			}
			selfdig20 = SharepreferencesUtilSystemSettings.getValue(
					getContext(), System_key_SelfAmout2, "200,000");
			selfdig50 = SharepreferencesUtilSystemSettings.getValue(
					getContext(), System_key_SelfAmout5, "500,000");
			selfdig100 = SharepreferencesUtilSystemSettings.getValue(
					getContext(), System_key_SelfAmout10, "1,000,000");
			selfdigkey();
			// mKeyboardView.setKeyboard(mKeyboard);
			mKeyboardView.setEnabled(true);
			mKeyboardView.setPreviewEnabled(false);
			mKeyboardView.setOnKeyboardActionListener(this);

			mKeyboardWindow = new PopupWindow(mKeyboardView,
					ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
			mKeyboardWindow.setAnimationStyle(R.style.AnimationFade);
			// mKeyboardWindow.setBackgroundDrawable(new BitmapDrawable());
			// mKeyboardWindow.setOutsideTouchable(true);
			mKeyboardWindow.setOnDismissListener(new OnDismissListener() {

				@Override
				public void onDismiss() {
					// TODO Auto-generated method stub
					if (scrolldis > 0) {
						int temp = scrolldis;
						// scrolldis = 0;
						if (null != mContentView) {
							mContentView.scrollBy(0, -temp);
						}
					}
				}
			});
		} else {
			needcustomkeyboard = false;
		}

		a.recycle();

	}

	private void showKeyboard() {
		if (null != mKeyboardWindow) {
			if (!mKeyboardWindow.isShowing()) {
				if (randomkeys) {
					randomdigkey(mKeyboard);
				}

				selfdig20 = SharepreferencesUtilSystemSettings.getValue(
						getContext(), System_key_SelfAmout2, "200,000");
				selfdig50 = SharepreferencesUtilSystemSettings.getValue(
						getContext(), System_key_SelfAmout5, "500,000");
				selfdig100 = SharepreferencesUtilSystemSettings.getValue(
						getContext(), System_key_SelfAmout10, "1,000,000");
				selfdigkey();
				// mKeyboardView.setKeyboard(mKeyboard);

				mKeyboardWindow.setAnimationStyle(R.style.AnimBottom);
				mKeyboardWindow.showAtLocation(this.mDecorView, Gravity.RIGHT
						| Gravity.BOTTOM, 0, 0);
				mKeyboardWindow.update();

				if (null != mDecorView && null != mContentView) {
					int[] pos = new int[2];
					// 计算弹出的键盘的尺寸
					getLocationOnScreen(pos);
					float height = dpToPx(getContext(), 240);

					// int []hsmlpos=new int[2];
					// mDecorView.getLocationOnScreen(hsmlpos);

					Rect outRect = new Rect();
					// 然后该View有个getWindowVisibleDisplayFrame()方法可以获取到程序显示的区域,
					// * 包括标题栏,但不包括状态栏。
					mDecorView.getWindowVisibleDisplayFrame(outRect);// 获得view空间,也就是除掉标题栏
					// outRect.top表示状态栏(通知栏)
					int screen = real_scontenth;
					// scrolldis = (int) ((pos[1] + getMeasuredHeight() -
					// outRect.top)
					// - (screen - height) + 500);

					if (scrolldis > 0) {
						mContentView.scrollBy(0, scrolldis);
					}
				}

			}
		}
	}

	private void hideKeyboard() {
		if (null != mKeyboardWindow) {
			if (mKeyboardWindow.isShowing()) {
				mKeyboardWindow.dismiss();
			}
		}
	}

	private void hideSysInput() {
		if (this.getWindowToken() != null) {
			InputMethodManager imm = (InputMethodManager) getContext()
					.getSystemService(Context.INPUT_METHOD_SERVICE);
			imm.hideSoftInputFromWindow(this.getWindowToken(), 0);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		super.onTouchEvent(event);
		requestFocus();
		requestFocusFromTouch();

		if (needcustomkeyboard) {
			hideSysInput();
			showKeyboard();
		}

		return true;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			if (null != mKeyboardWindow) {
				if (mKeyboardWindow.isShowing()) {
					mKeyboardWindow.dismiss();
					return true;
				}
			}
		}

		return super.onKeyDown(keyCode, event);

	}

	@Override
	public void onAttachedToWindow() {
		super.onAttachedToWindow();

		this.mWindow = ((Activity) getContext()).getWindow();
		this.mDecorView = this.mWindow.getDecorView();
		this.mContentView = this.mWindow
				.findViewById(Window.ID_ANDROID_CONTENT);

		hideSysInput();
	}

	@Override
	public void onDetachedFromWindow() {
		super.onDetachedFromWindow();

		hideKeyboard();

		mKeyboardWindow = null;
		mKeyboardView = null;
		mKeyboard = null;

		mDecorView = null;
		mContentView = null;
		mWindow = null;
	}

	@Override
	public void onPress(int primaryCode) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onRelease(int primaryCode) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onKey(int primaryCode, int[] keyCodes) {
		// TODO Auto-generated method stub
		Editable editable = this.getText();
		int start = this.getSelectionStart();
		if (primaryCode == Keyboard.KEYCODE_CANCEL) {// 隐藏键盘
			hideKeyboard();
		} else if (primaryCode == Keyboard.KEYCODE_DELETE) {// 回退
			if (editable != null && editable.length() > 0) {
	<span style="color:#cc0000;">			if (start > 0) {
					String keyValue = editable.toString();
					String newValue = keyValue.substring(0,
							keyValue.length() - 1);
					newValue = newValue.replace(",", "");
					if (!newValue.equals("")) {
						double amount = Double.parseDouble(newValue);
						String amountStr = DecimalUtil.formatAmount(amount);

						editable.clear();
						editable.insert(0, amountStr);
					} else {
						editable.clear();
						editable.insert(0, "");
					}</span>
				}
			}
		} else if (primaryCode == Keyboard.KEYCODE_SHIFT) {// 大小写切换
			changeKey();
			mKeyboardView.setKeyboard(k1);

		}

		else if (primaryCode == Keyboard.KEYCODE_DONE) {// 标点符号键盘切换
			if (isnun) {
				isnun = false;
				mKeyboardView.setKeyboard(k1);
			} else {
				isnun = true;
				mKeyboardView.setKeyboard(k2);
			}
		} else if (primaryCode == 46) {

			// 当用户输入.3的时候自动转换为0.3
			if (editable != null && editable.length() > 0) {
				if (start > 0) {
					editable.insert(start, ".");
				}
			} else {
				editable.insert(start, "0.");
			}

		}

		else if (primaryCode == -110) {
			editable.insert(start, "00");
		} else if (primaryCode == -20000) {
			editable.clear();
			editable.insert(0, selfdig20);
		} else if (primaryCode == -50000) {
			editable.clear();
			editable.insert(0, selfdig50);
		} else if (primaryCode == -10000) {
			editable.clear();
			editable.insert(0, selfdig100);
		} else if (0x0 <= primaryCode && primaryCode <= 0x7f) {
			// 可以直接输入的字符(如0-9,.),他们在键盘映射xml中的keycode值必须配置为该字符的ASCII码
			editable.insert(start, Character.toString((char) primaryCode));
		} else if (primaryCode > 0x7f) {
			Key mkey = getKeyByKeyCode(primaryCode);
			// 可以直接输入的字符(如0-9,.),他们在键盘映射xml中的keycode值必须配置为该字符的ASCII码
			editable.insert(start, mkey.label);

		} else {
			// 其他一些暂未开放的键指令,如next到下一个输入框等指令
		}
	}

	// 数字键盘测试是否改变200,000和500,000让用户自定义

	private void selfdigkey() {
		if (mKeyboard == null) {
			return;
		}

		List<Key> keyList = k3.getKeys();

		// 查找出0-9的数字键
		for (int i = 0, size = keyList.size(); i < size; i++) {
			Key key = keyList.get(i);

			CharSequence label = key.label;
			// if (label != null && label.toString().equals(orgindi20)) {
			// keyList.get(i).label = selfdig;
			// orgindi20 = selfdig;
			// }

			if (label != null && label.toString().equals(orgindi20)) {
				keyList.get(i).label = selfdig20;
				keyList.get(i).codes[0] = -20000;
				orgindi20 = selfdig20;
			}
			if (label != null && label.toString().equals(orgindi50)) {
				keyList.get(i).label = selfdig50;
				keyList.get(i).codes[0] = -50000;
				orgindi50 = selfdig50;
			}
			if (label != null && label.toString().equals(orgindi100)) {
				keyList.get(i).label = selfdig100;
				keyList.get(i).codes[0] = -10000;
				orgindi100 = selfdig100;
			}
		}

		mKeyboardView.setKeyboard(k3);
	}

	/**
	 * 键盘大小写切换
	 */
	private void changeKey() {
		List<Key> keylist = k1.getKeys();
		if (isupper) {// 大写切换小写
			isupper = false;
			for (Key key : keylist) {
				if (key.label != null && isword(key.label.toString())) {
					key.label = key.label.toString().toLowerCase();
					key.codes[0] = key.codes[0] + 32;
				}
			}
		} else {// 小写切换大写
			isupper = true;
			for (Key key : keylist) {
				if (key.label != null && isword(key.label.toString())) {
					key.label = key.label.toString().toUpperCase();
					key.codes[0] = key.codes[0] - 32;
				}
			}
		}
	}

	private boolean isword(String str) {
		String wordstr = "abcdefghijklmnopqrstuvwxyz";
		if (wordstr.indexOf(str.toLowerCase()) > -1) {
			return true;
		}
		return false;
	}

	@Override
	public void onText(CharSequence text) {
		// TODO Auto-generated method stub

	}

	@Override
	public void swipeLeft() {
		// TODO Auto-generated method stub

	}

	@Override
	public void swipeRight() {
		// TODO Auto-generated method stub

	}

	@Override
	public void swipeDown() {
		// TODO Auto-generated method stub

	}

	@Override
	public void swipeUp() {
		// TODO Auto-generated method stub

	}

	private Key getKeyByKeyCode(int keyCode) {
		if (null != mKeyboard) {
			List<Key> mKeys = mKeyboard.getKeys();
			for (int i = 0, size = mKeys.size(); i < size; i++) {
				Key mKey = mKeys.get(i);

				int codes[] = mKey.codes;

				if (codes[0] == keyCode) {
					return mKey;
				}
			}
		}

		return null;
	}

	private void initAttributes(Context context) {

		k1 = new Keyboard(context, R.xml.qwerty);
		k2 = new Keyboard(context, R.xml.qwerty2);
		k3 = new Keyboard(context, R.xml.amountinputkeyboard);

		initScreenParams(context);
		this.setLongClickable(false);
		this.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
		removeCopyAbility();

		if (this.getText() != null) {
			this.setSelection(this.getText().length());
		}

		this.setOnFocusChangeListener(new OnFocusChangeListener() {

			@Override
			public void onFocusChange(View v, boolean hasFocus) {
				// TODO Auto-generated method stub
				if (!hasFocus) {
					hideKeyboard();
				}
			}
		});

	}

	@TargetApi(11)
	private void removeCopyAbility() {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
			this.setCustomSelectionActionModeCallback(new ActionMode.Callback() {

				@Override
				public boolean onCreateActionMode(ActionMode mode, Menu menu) {
					return false;
				}

				@Override
				public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
					return false;
				}

				@Override
				public void onDestroyActionMode(ActionMode mode) {

				}

				@Override
				public boolean onActionItemClicked(ActionMode mode,
						MenuItem item) {
					return false;
				}
			});
		}
	}

	private boolean isNumber(String str) {
		String wordstr = "0123456789";
		if (wordstr.indexOf(str) > -1) {
			return true;
		}
		return false;
	}

	private void randomdigkey(Keyboard mKeyboard) {
		if (mKeyboard == null) {
			return;
		}

		List<Key> keyList = mKeyboard.getKeys();

		// 查找出0-9的数字键
		List<Key> newkeyList = new ArrayList<Key>();
		for (int i = 0, size = keyList.size(); i < size; i++) {
			Key key = keyList.get(i);
			CharSequence label = key.label;
			if (label != null && isNumber(label.toString())) {
				newkeyList.add(key);
			}
		}

		int count = newkeyList.size();

		List<KeyModel> resultList = new ArrayList<KeyModel>();

		LinkedList<KeyModel> temp = new LinkedList<KeyModel>();

		for (int i = 0; i < count; i++) {
			temp.add(new KeyModel(48 + i, i + ""));
		}

		Random rand = new SecureRandom();
		rand.setSeed(SystemClock.currentThreadTimeMillis());

		for (int i = 0; i < count; i++) {
			int num = rand.nextInt(count - i);
			KeyModel model = temp.get(num);
			resultList.add(new KeyModel(model.getCode(), model.getLable()));
			temp.remove(num);
		}

		for (int i = 0, size = newkeyList.size(); i < size; i++) {
			Key newKey = newkeyList.get(i);
			KeyModel resultmodle = resultList.get(i);
			newKey.label = resultmodle.getLable();
			newKey.codes[0] = resultmodle.getCode();
		}

	}

	class KeyModel {

		private Integer code;
		private String label;

		public KeyModel(Integer code, String lable) {
			this.code = code;
			this.label = lable;
		}

		public Integer getCode() {
			return code;
		}

		public void setCode(Integer code) {
			this.code = code;
		}

		public String getLable() {
			return label;
		}

		public void setLabel(String lable) {
			this.label = lable;
		}

	}

	/**
	 * 密度转换为像素值
	 * 
	 * @param dp
	 * @return
	 */
	public static int dpToPx(Context context, float dp) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (dp * scale + 0.5f);
	}

	private void initScreenParams(Context context) {
		DisplayMetrics dMetrics = new DisplayMetrics();
		WindowManager windowManager = (WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE);
		Display display = windowManager.getDefaultDisplay();
		display.getMetrics(dMetrics);

		screenw = dMetrics.widthPixels;
		screenh = dMetrics.heightPixels;
		density = dMetrics.density;
		densityDpi = dMetrics.densityDpi;

		screenh_nonavbar = screenh;

		int ver = Build.VERSION.SDK_INT;

		// 新版本的android 系统有导航栏,造成无法正确获取高度
		if (ver == 13) {
			try {
				Method mt = display.getClass().getMethod("getRealHeight");
				screenh_nonavbar = (Integer) mt.invoke(display);
			} catch (Exception e) {
			}
		} else if (ver > 13) {
			try {
				Method mt = display.getClass().getMethod("getRawHeight");
				screenh_nonavbar = (Integer) mt.invoke(display);
			} catch (Exception e) {
			}
		}

		real_scontenth = screenh_nonavbar - getStatusBarHeight(context);

	}

	/**
	 * 电量栏高度
	 * 
	 * @return
	 */
	public static int getStatusBarHeight(Context context) {
		Class<?> c = null;
		Object obj = null;
		Field field = null;
		int x = 0, sbar = 0;
		try {
			c = Class.forName("com.android.internal.R$dimen");
			obj = c.newInstance();
			field = c.getField("status_bar_height");
			x = Integer.parseInt(field.get(obj).toString());
			sbar = context.getResources().getDimensionPixelSize(x);
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		return sbar;
	}

}

有问题可以问我,这个百度上都没有很好的解决方案,如果有遇到同样的需求的同行,可以相互交流

你可能感兴趣的:(android,EditText,限制小数位数)