先上图
说明
在有自定义的输入键盘对 EditText 控件进行赋值的情况下,以友好的方式处理金额的输入。
1、纯数字中间输入小数点时,会自动保留两位小数,移除多余位数;
2、纯数字前面直接输入0时,会自动补齐后面的小数点,同时保留两位小数;
3、0和小数点之间不允许再输入任何数字;
4、最多只能输入一个小数点;
5、纯数字前面直接输入小数点时,会自动补齐前面的0,同时保留两位小数;
6、当删除数字时,如果删除了小数点会进行数字最大值的限制判断;
7、当删除数字时,如果前面有多余的0位,则会移除多余的0;
8、当删除数字时,如果整个数字的实际值为0时,则只会保留一个0;
9、还有其它的处理方式,如:数字格式为0.XX,如果此时光标在小数点后,进行删除,则会自动删除0和.,变成XX;
可能有部分情况处理有bug,目前的处理方式已经包括了绝大多数情况,只要小心调试就可以修复未知问题;
实现
主要是要在输入的不同数字内容时,进行相关的业务判断处理。
package com.windfallsheng.inputamountwithkeyboard;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import static com.windfallsheng.inputamountwithkeyboard.CashFragment.AmountKeyboard.EIGHT;
import static com.windfallsheng.inputamountwithkeyboard.CashFragment.AmountKeyboard.FIVE;
import static com.windfallsheng.inputamountwithkeyboard.CashFragment.AmountKeyboard.FOUR;
import static com.windfallsheng.inputamountwithkeyboard.CashFragment.AmountKeyboard.NINE;
import static com.windfallsheng.inputamountwithkeyboard.CashFragment.AmountKeyboard.ONE;
import static com.windfallsheng.inputamountwithkeyboard.CashFragment.AmountKeyboard.POINTER;
import static com.windfallsheng.inputamountwithkeyboard.CashFragment.AmountKeyboard.SEVEN;
import static com.windfallsheng.inputamountwithkeyboard.CashFragment.AmountKeyboard.SIX;
import static com.windfallsheng.inputamountwithkeyboard.CashFragment.AmountKeyboard.THREE;
import static com.windfallsheng.inputamountwithkeyboard.CashFragment.AmountKeyboard.TWO;
import static com.windfallsheng.inputamountwithkeyboard.CashFragment.AmountKeyboard.ZERO;
/**
* @Author: lzsheng
* @date: 2021/11/11 10:53
* @description:
*/
public class CashFragment extends Fragment implements View.OnClickListener {
private final String TAG = "CashFragment";
private View mContainer;
private EditText mEtAmount;
private View mKeyPoint;
private View mBtnDel;
public static CashFragment newInstance() {
CashFragment fragment = new CashFragment();
// Bundle args = new Bundle();
// args.putString(ARG_PARAM1, param1);
// args.putString(ARG_PARAM2, param2);
// fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// if (getArguments() != null) {
// mParam1 = getArguments().getString(ARG_PARAM1);
// mParam2 = getArguments().getString(ARG_PARAM2);
// }
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mContainer = inflater.inflate(R.layout.fragment_cash, container, false);
return mContainer;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initViews();
}
private void initViews() {
mEtAmount = mContainer.findViewById(R.id.edt_code);
mContainer.findViewById(R.id.key_1).setOnClickListener(this);
mContainer.findViewById(R.id.key_2).setOnClickListener(this);
mContainer.findViewById(R.id.key_3).setOnClickListener(this);
mContainer.findViewById(R.id.key_4).setOnClickListener(this);
mContainer.findViewById(R.id.key_5).setOnClickListener(this);
mContainer.findViewById(R.id.key_6).setOnClickListener(this);
mContainer.findViewById(R.id.key_7).setOnClickListener(this);
mContainer.findViewById(R.id.key_8).setOnClickListener(this);
mContainer.findViewById(R.id.key_9).setOnClickListener(this);
mContainer.findViewById(R.id.key_0).setOnClickListener(this);
mKeyPoint = mContainer.findViewById(R.id.key_point);
mKeyPoint.setOnClickListener(CashFragment.this);
mContainer.findViewById(R.id.key_confirm).setOnClickListener(this);
mBtnDel = mContainer.findViewById(R.id.rlayout_del);
//EditText的InputType设置格式
// android:inputType="numberDecimal"
// //或者
// mEtAmount.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
mEtAmount.setLongClickable(false);
UIHelper.disableSoftInput(getActivity(), mEtAmount);
UIHelper.disableEditTextCopyAndPaste(mEtAmount);
mEtAmount.requestFocus();
//设置金额输入的过滤器,保证只能输入金额类型;
// InputFilter[] filters={new CashierInputFilter()};
// mEtAmount.setFilters(filters);
// mEtAmount.addTextChangedListener(new TextWatcher() {
// @Override
// public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Log.d(TAG, "mEtAmount#beforeTextChanged#s=" + s.toString() + ", start=" + start
// + ", count=" + count + ", after=" + after);
// }
//
// @Override
// public void onTextChanged(CharSequence s, int start, int before, int count) {
// mAmountInput = s.toString().trim();
// Log.d(TAG, "mEtAmount#onTextChanged#s=" + s.toString() + ", start=" + start
// + ", count=" + count);
// }
//
// @Override
// public void afterTextChanged(Editable s) {
// Log.d(TAG, "mEtAmount#afterTextChanged#s=" + s.toString());
// }
// });
mBtnDel.setOnClickListener(v -> {
String amountInput = mEtAmount.getText().toString().trim();
if (TextUtils.isEmpty(amountInput)) {
return;
}
int indexSelection = mEtAmount.getSelectionStart();
if (amountInput.contains(POINTER)) {
int indexPointer = amountInput.indexOf(POINTER);
if (amountInput.startsWith("0.")) {
// 此时不能再删除这里的0;
if (indexSelection <= indexPointer) {
return;
}
}
if ((indexPointer + 1) == indexSelection) {
if (amountInput.startsWith("0.")) {
// 此时需要移除0和小数点位;
amountInput = amountInput.substring("0.".length());
mEtAmount.setText(amountInput);
amountInput = mEtAmount.getText().toString().trim();
mEtAmount.setSelection(amountInput.length());
return;
}
// 光标在小数点后的情况,此时需要控制删除后数字的大小
final String replace = amountInput.replace(POINTER, "");
if (StringUtils.hasAmountOverLimit(replace)) {
ToastUtils.showToast(getActivity(), "收款金额超过100,000限制");
return;
}
}
}
handleBtnDeleteDown();
String formatAmount = StringUtils.formatAmount(amountInput);
if (TextUtils.isEmpty(formatAmount)) {
mEtAmount.setText("");
mEtAmount.setSelection(0);
return;
} else {
if (!TextUtils.equals(ZERO, amountInput)) {
boolean isZero = StringUtils.isZeroAmount(formatAmount);
if (isZero) {
// 验证金额格式;
// if (TextUtils.equals("0", amountInput) ||
// TextUtils.equals("0.0", amountInput) ||
// TextUtils.equals("0.00", amountInput)) {
mEtAmount.setText("0");
mEtAmount.setSelection(1);
// }
return;
}
}
}
// 调用删除后重新获取输入的位置
indexSelection = mEtAmount.getSelectionStart();
if (amountInput.contains(POINTER)) {
if (indexSelection == 0) {
// 输入位置在首位,但后面是小数点时,自动补0到首位;
if (amountInput.startsWith(POINTER)) {
handleAmountInputEditText(ZERO);
return;
} else {
// 移除 0000.XX 或者 0006005.XX 前面的无效0位;
if (amountInput.startsWith(ZERO) && !amountInput.startsWith("0.")) {
for (; ; ) {
if (amountInput.startsWith(ZERO) && !amountInput.startsWith("0.")) {
amountInput = amountInput.substring(1);
} else {
break;
}
}
mEtAmount.setText(amountInput);
}
}
}
} else {
// 移除 000306 前面的无效0位;
if (amountInput.startsWith(ZERO)) {
for (; ; ) {
if (amountInput.startsWith(ZERO)) {
amountInput = amountInput.substring(1);
} else {
break;
}
}
mEtAmount.setText(amountInput);
}
}
});
// mBtnDel.setOnLongClickListener(v -> {
// Timer timer = new Timer();
// TimerTask mTask = new TimerTask() {
// @Override
// public void run() {
// mBtnDel.post(() -> {
// if (mBtnDel.isPressed() && mEtAmount.getText().length() > 0) {
// int keyCode = KeyEvent.KEYCODE_DEL;
// KeyEvent keyEventDown = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
// KeyEvent keyEventUp = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
// mEtAmount.onKeyDown(keyCode, keyEventDown);
// mEtAmount.onKeyUp(keyCode, keyEventUp);
// } else {
// timer.cancel();
// }
// });
// }
// };
// timer.schedule(mTask, 0, 100);
// return false;
// });
}
private void handleBtnDeleteDown() {
int keyCode = KeyEvent.KEYCODE_DEL;
KeyEvent keyEventDown = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
KeyEvent keyEventUp = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
mEtAmount.onKeyDown(keyCode, keyEventDown);
mEtAmount.onKeyUp(keyCode, keyEventUp);
}
@Override
public void onClick(View v) {
String tag = (String) v.getTag();
String amountInput = mEtAmount.getText().toString().trim();
// 输入的位置
int indexSelectionStart = mEtAmount.getSelectionStart();
switch (tag) {
case POINTER:
// 内容为空或者已经有小数点,则不能再输入小数点;
if (TextUtils.isEmpty(amountInput)) {
break;
}
// 已经有小数点,则不能再输入小数点;
if (amountInput.contains(POINTER)) {
ToastUtils.showToast(getActivity(), "已经输入小数点");
break;
}
if (indexSelectionStart == 0) {
// 没有小数点->输入位置在首位;
UIHelper.inputEditText(mEtAmount, tag);
// 在首位补0;
mEtAmount.setSelection(0);
UIHelper.inputEditText(mEtAmount, ZERO);
String content = substringIfTwoDecimalPlaces(mEtAmount);
mEtAmount.setText(content);
amountInput = mEtAmount.getText().toString().trim();
mEtAmount.setSelection(amountInput.length());
break;
} else {
// 没有小数点->输入位置在其它位;
UIHelper.inputEditText(mEtAmount, tag);
String content = substringIfTwoDecimalPlaces(mEtAmount);
mEtAmount.setText(content);
amountInput = mEtAmount.getText().toString().trim();
mEtAmount.setSelection(amountInput.indexOf(POINTER) + 1);
}
break;
case ZERO:
if (TextUtils.isEmpty(amountInput)) {
handleAmountInputEditText(tag);
break;
}
// 有小数点的情况;
if (amountInput.contains(POINTER)) {
if (indexSelectionStart == 0) {
int pointerIndex = amountInput.indexOf(POINTER);
// 如果是删除后,第一位是小数点,则可以输入0,否则不可以;
if (pointerIndex == 0) {
handleAmountInputEditText(tag);
break;
}
// 有小数点的情况->第一位不是小数点,则不参再输入0;
ToastUtils.showToast(getActivity(), "已经输入小数点");
break;
}
int pointerIndex = amountInput.indexOf(POINTER);
// 在小数点前输入的情况;
if (indexSelectionStart <= pointerIndex) {
// 首位已经是0
if (amountInput.startsWith(ZERO)) {
// 首位已经是0,则在首位的0到小数点之间不能再输入0;
int indexZero = amountInput.indexOf(ZERO);
if (indexSelectionStart >= indexZero && indexSelectionStart <= pointerIndex) {
break;
}
}
// 在小数点前输入的情况->其它可输入0的情况;
handleAmountInputEditText(tag);
} else {
// 在小数点后输入0;
// 首位已经是0->在小数点后输入0;
if (indexSelectionStart == amountInput.length()) {
// 在末位输入需要有提示
if (hasTwoDecimalPlaces(amountInput)) {
ToastUtils.showShortToast(getActivity(), "小数点后只能输入两位");
break;
}
}
handleAmountInputEditText(tag);
// 在小数点后输入则需要限止小数点位数;
String content = substringIfTwoDecimalPlaces(mEtAmount);
mEtAmount.setText(content);
amountInput = mEtAmount.getText().toString().trim();
int index = indexSelectionStart + 1;
if (index > amountInput.length()) {
index = amountInput.length();
}
mEtAmount.setSelection(index);
break;
}
} else {
// 没有小数点的情况;
if (indexSelectionStart == 0) {
// 没有小数点的情况->在首位输入0的情况;
handleAmountInputEditText(tag);
// 0和小数点一起输入,同时将数据转换成正确格式;
amountInput = mEtAmount.getText().toString().trim();
if (amountInput.startsWith("0")) {
// 在输入0后,紧跟0位自动补小数点;
UIHelper.inputEditText(mEtAmount, POINTER);
// 添加小数点后如果位置过长则限制小数点后两位;
String content = substringIfTwoDecimalPlaces(mEtAmount);
mEtAmount.setText(content);
amountInput = mEtAmount.getText().toString().trim();
mEtAmount.setSelection(amountInput.indexOf(POINTER) + 1);
}
break;
}
boolean isZero = StringUtils.isZeroAmount(amountInput);
if (isZero) {
// 无小数的情况->输入的结果是值是0,则不再继续输入0;
break;
}
// 其它可输入0的情况;
handleAmountInputEditText(tag);
}
break;
case ONE:
case TWO:
case THREE:
case FOUR:
case FIVE:
case SIX:
case SEVEN:
case EIGHT:
case NINE:
if (TextUtils.isEmpty(amountInput)) {
handleAmountInputEditText(tag);
return;
}
// 有小数的情况;
if (amountInput.contains(POINTER)) {
int pointerIndex = amountInput.indexOf(POINTER);
// 有小数的情况->小数点前输入;
if (indexSelectionStart <= pointerIndex) {
if (amountInput.startsWith(ZERO)) {
// 首位已经是0,如:0.XX,则0后至小数点之间不能输入任何数字;
int zeroIndex = amountInput.indexOf(ZERO);
if (indexSelectionStart > zeroIndex && indexSelectionStart <= pointerIndex) {
break;
}
}
handleAmountInputEditText(tag);
break;
} else {
// 有小数的情况->小数点后输入;
if (indexSelectionStart == amountInput.length()) {
// 在末位输入需要有提示
if (hasTwoDecimalPlaces(amountInput)) {
ToastUtils.showShortToast(getActivity(), "小数点后只能输入两位");
break;
}
}
handleAmountInputEditText(tag);
// 在小数点后输入则需要限止小数点位数;
String content = substringIfTwoDecimalPlaces(mEtAmount);
mEtAmount.setText(content);
amountInput = mEtAmount.getText().toString().trim();
int index = indexSelectionStart + 1;
if (index > amountInput.length()) {
index = amountInput.length();
}
mEtAmount.setSelection(index);
break;
}
} else {
// 没有小数的情况;
if (amountInput.startsWith("0")) {
// 没有小数的情况->首位已经是0,后面不能紧跟着输入数字;
int zeroIndex = amountInput.indexOf(ZERO);
if (indexSelectionStart > zeroIndex) {
break;
}
}
// 没有小数的情况->其它可以输入的情况;
handleAmountInputEditText(tag);
}
break;
case "confirm":
String amountStr = mEtAmount.getText().toString().trim();
// 验证金额格式;
boolean isZero = StringUtils.isZeroAmount(amountStr);
if (isZero) {
ToastUtils.showShortToast(getActivity(), "输入的金额应大于0");
return;
}
// 验证金额格式;
ResultWrapper resultWrapper = StringUtils.isValidAmountOnly(amountStr);
if (!resultWrapper.isSuccessful()) {
ToastUtils.showShortToast(getActivity(), resultWrapper.getMsg());
return;
}
ToastUtils.showShortToast(getActivity(), "输入金额为" + amountStr);
// mEtAmount.setText("");
break;
default:
break;
}
}
private void handleAmountInputEditText(String tag) {
String msg = UIHelper.inputAmountToEditText(mEtAmount, tag);
if (!TextUtils.isEmpty(msg)) {
ToastUtils.showToast(getActivity(), msg);
}
}
private String removeZeroOfStart(String content) {
if (TextUtils.isEmpty(content)) {
return content;
}
if (content.startsWith(ZERO)) {
for (; ; ) {
if (content.startsWith(ZERO)) {
content = content.substring(1);
} else {
break;
}
}
}
return content;
}
/**
* 验证小数字点是否有两位;超过返回false;
*
* @param amount
* @param etAmount
* @return
*/
private boolean validPointAfter(String amount, EditText etAmount) {
if (!TextUtils.isEmpty(amount) && amount.contains(".")) {
int indexPoint = amount.indexOf(".");
String substring = amount.substring(indexPoint + 1);
if (substring.length() > 1) {
int indexSelection = etAmount.getSelectionStart();
if (indexSelection <= indexPoint) {
// 如果光标在小数点前面的位置,则可以继续输入;
} else {
return false;
}
}
}
return true;
}
/**
* 是否已经两位或者超过两位小数;
*
* @param content
* @return
*/
private boolean hasTwoDecimalPlaces(String content) {
if (TextUtils.isEmpty(content)) {
return false;
}
if (content.contains(POINTER)) {
int indexPoint = content.indexOf(POINTER);
int length = content.length();
if (length - indexPoint > 2) {
return true;
}
}
return false;
}
/**
* 如果小数点超过两位,就截取字符串保留两位小数;
*
* @param editText
* @return
*/
private String substringIfTwoDecimalPlaces(EditText editText) {
String content = editText.getText().toString().trim();
if (!TextUtils.isEmpty(content) && content.contains(".")) {
int indexPoint = content.indexOf(POINTER);
int length = content.length();
if (length - indexPoint > 2) {
content = content.substring(0, indexPoint + 3);
}
}
return content;
}
/**
* 验证小数字点是否有两位;超过返回false;
*
* @param amount
* @param etAmount
* @return
*/
private boolean validZeroAfter(String amount, EditText etAmount) {
if (!TextUtils.isEmpty(amount) && amount.contains(".")) {
int indexPoint = amount.indexOf(POINTER);
String substring = amount.substring(indexPoint + 1);
if (substring.length() > 1) {
int indexSelection = etAmount.getSelectionStart();
if (indexSelection <= indexPoint) {
// 如果光标在小数点前面的位置,则可以继续输入;
} else {
return false;
}
}
}
return true;
}
/**
* 数字输入键盘的值;
*/
public static class AmountKeyboard {
/**
*
*/
public static final String POINTER = ".";
public static final String ZERO = "0";
public static final String ONE = "1";
public static final String TWO = "2";
public static final String THREE = "3";
public static final String FOUR = "4";
public static final String FIVE = "5";
public static final String SIX = "6";
public static final String SEVEN = "7";
public static final String EIGHT = "8";
public static final String NINE = "9";
}
}
package com.windfallsheng.inputamountwithkeyboard;
import android.text.TextUtils;
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class StringUtils {
/**
* 字符串是否为空或者为字符串"null"、"Null"等;
*
* @param content
* @return
*/
public static boolean isEmpty(String content) {
if (TextUtils.isEmpty(content)) {
return true;
} else if (TextUtils.equals(content.toLowerCase(), "null")) {
return true;
}
return false;
}
/**
* 判断金额是否是0,如,0.0或00000;
*
* @param amount
* @return
*/
public static boolean isZeroAmount(String amount) {
if (TextUtils.isEmpty(amount)) {
return false;
}
if (amount.contains(".")) {
amount = amount.replaceAll("\\.", "");
}
char[] charArray = amount.toCharArray();
// 是否是0;
int countZero = 0;
for (int i = 0; i < charArray.length; i++) {
char c = charArray[i];
if (TextUtils.equals("0", String.valueOf(c))) {
countZero++;
}
}
if (countZero == charArray.length) {
return true;
}
return false;
}
/**
* 判断金额是否是有效的,如,732或102.68;
*
* @param amount
* @return
*/
public static ResultWrapper isValidAmountOnly(String amount) {
if (TextUtils.isEmpty(amount)) {
return new ResultWrapper(0, false, "金额为空");
}
amount = amount.trim();
if (amount.contains(" ")) {
amount = amount.replaceAll(" ", "");
}
if (amount.contains(",")) {
amount = amount.replaceAll(",", "");
}
if (amount.contains("¥")) {
amount = amount.replaceAll("¥", "");
}
if (amount.contains("¥")) {
amount = amount.replaceAll("¥", "");
}
if (TextUtils.isEmpty(amount)) {
return new ResultWrapper(0, false, "金额为空");
}
// 处理前面有无效的0,或者以小数点开头的情况;
if (amount.contains(".")) {
// 有小数点->以小数点开头的情况;
int indexPointer = amount.indexOf(".");
if (indexPointer == 0) {
return new ResultWrapper(0, false, "金额以小数点开头");
}
// 有小数点->有无效的0位;
if (amount.startsWith("0")) {
// 有无效的0位,如:00.XX、006005.XX,而0.1、0.01,或者30.06是有效的;
if (indexPointer > 1) {
return new ResultWrapper(0, false, "金额有无效的0位开头");
}
}
} else {
// 没有小数点->首位有无效的0的情况;
if (amount.startsWith("0")) {
// 无效的0位,如:0056、006005;
return new ResultWrapper(0, false, "金额有无效的0位开头");
}
}
if (hasAmountOverLimit(amount)) {
return new ResultWrapper(0, false, "收款金额超过100,000限制");
}
// ASCII码表中0~9是48~57,小数点为46, “,”为44;
char[] charArray = amount.toCharArray();
// 小数点后有几位,这个计算是包含小数点位的;
int countAfterPoint = 0;
// 是否多于两个小数点;
int countPoint = 0;
for (int i = 0; i < charArray.length; i++) {
char c = charArray[i];
boolean isDigitsForAmount = isDigitsForAmount(c);
if (!isDigitsForAmount) {
return new ResultWrapper(0, false, "金额不能输入数字和小数点之外的内容");
}
// 是否多于两个小数点;
if (TextUtils.equals(".", String.valueOf(c))) {
countPoint++;
}
// 如果有小数点,则检查小数点后有几位;
if (countPoint >= 1) {
countAfterPoint++;
}
}
if (countPoint > 1) {
return new ResultWrapper(0, false, "金额小数点多于1位");
}
// 如果有小数点,则检查小数点后有几位;
if (countAfterPoint > 3) {
return new ResultWrapper(0, false, "金额小数点后最多保留2位");
}
return new ResultWrapper(0, true, "金额格式正确");
}
public static boolean hasAmountOverLimit(String amount) {
return hasAmountOverLimit(amount, new BigDecimal(100000.00));
}
public static boolean hasAmountOverLimit(String amount, BigDecimal limit) {
// BigDecimal比较大小使用compareTo(BigDecimal)方法。
// int flag = bigdemical.compareTo(bigdemical1)
// flag = -1,表示bigdemical小于bigdemical1;
// flag = 0,表示bigdemical等于bigdemical1;
// flag = 1,表示bigdemical大于bigdemical1;
BigDecimal bigDecimal = new BigDecimal(amount);
return bigDecimal.compareTo(limit) > -1;
}
/**
* 是否是金额格式中正确的字符,包括仅包含小数点“.”、分割符“,”和0~9这些字符。
* <p>
* ASCII码表中0~9是48~57,小数点为46, “,”为44;
*
* @param c
* @return
*/
private static boolean isDigitsForAmount(char c) {
int d = c;
// 字符是小数点;
if (d == 46) {
return true;
}
// 字符是0~9;
if (d >= 48 && d <= 57) {
return true;
}
// 字符是,号分割符;
if (d == 44) {
return true;
}
return false;
}
/**
* 判断是否是纯数字,没有小数且不是0;
*
* @return
*/
public static boolean isDigitsOnly(String str) {
if (!TextUtils.isEmpty(str) && !TextUtils.equals("0", str) && !str.contains(".") &&
TextUtils.isDigitsOnly(str)) {
return true;
}
return false;
}
/**
* 格式如:1,080,665,112.56
*
* @return
*/
public static String format2DecimalDefault(String amountStr) {
String str = formatAmountStr(amountStr);
return format2Decimal(str);
}
/**
* 返回格式为123112.01;
*
* @param amountStr
* @return
*/
public static String formatAmountStr(String amountStr) {
if (TextUtils.isEmpty(amountStr)) {
return "0";
}
if (amountStr.contains(",")) {
amountStr = amountStr.replace(",", "");
}
if (!TextUtils.isEmpty(amountStr)) {
amountStr = amountStr.replace("¥", "");
amountStr = amountStr.replace("¥", "");
}
//如果包含空格去掉
if (amountStr.contains(" ")) {
amountStr = amountStr.replace(" ", "");
}
// 是否包含多少小数点
char[] charArray = amountStr.toCharArray();
int count = 0;
for (char c : charArray) {
if (TextUtils.equals(".", String.valueOf(c))) {
count++;
}
}
if (count > 1) {
return "0";
}
return amountStr;
}
/**
* 格式如:1,080,665,112.56
*
* @return
*/
public static String format2Decimal(String amountStr) {
// 正确的定义方式是使用字符串构造函数:
if (TextUtils.isEmpty(amountStr)) {
return "0.00";
}
BigDecimal amount = new BigDecimal(amountStr);
DecimalFormat decimalFormat = new DecimalFormat("###,##0.00");
return decimalFormat.format(amount);
}
/**
* 格式如:1,080,665,112.56
*
* @return
*/
public static String format2Decimal(String amountStr, String def) {
// 正确的定义方式是使用字符串构造函数:
if (TextUtils.isEmpty(amountStr)) {
return TextUtils.isEmpty(def) ? "0.00" : def;
}
BigDecimal amount = new BigDecimal(amountStr);
DecimalFormat decimalFormat = new DecimalFormat("###,##0.00");
return decimalFormat.format(amount);
}
/**
* null 转 target
*
* @param origin
* @param target
* @return
*/
public static String null2String(CharSequence origin, String target) {
if (TextUtils.isEmpty(origin) || TextUtils.equals("null", origin.toString().toLowerCase())) {
return target;
}
return origin.toString();
}
/**
* null 转 ""
*
* @param origin
* @return
*/
public static String null2String(CharSequence origin) {
return null2String(origin, "");
}
/**
* 地区格式处理
*
* @param provinceName
* @param cityName
* @return
*/
public static String formatAreaStr(String provinceName, String cityName) {
String area = "";
provinceName = null2String(provinceName);
cityName = null2String(cityName);
if (!TextUtils.isEmpty(provinceName) && !TextUtils.isEmpty(cityName)) {
area = provinceName + "-" + cityName;
} else if (TextUtils.isEmpty(provinceName)) {
area = cityName;
} else if (TextUtils.isEmpty(cityName)) {
area = provinceName;
}
return area;
}
public static String formatAmount(String amount) {
if (!TextUtils.isEmpty(amount)) {
amount = amount.trim();
if (amount.contains(" ")) {
amount = amount.replaceAll(" ", "");
}
if (amount.contains(",")) {
amount = amount.replaceAll(",", "");
}
if (amount.contains("¥")) {
amount = amount.replaceAll("¥", "");
}
if (amount.contains("¥")) {
amount = amount.replaceAll("¥", "");
}
}
return amount;
}
}
package com.windfallsheng.inputamountwithkeyboard;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.text.InputFilter;
import android.text.Spanned;
import android.text.TextUtils;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class UIHelper {
/**
* 关闭键盘输入法
*
* @param context
* @param v
*/
public static void closeSoftInput(Context context, View v) {
if (v != null) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
/**
* 禁止EditText系统软键盘并使光标正常显示
*
* @param activity
* @param editText
*/
public static void disableSoftInput(Activity activity, EditText editText) {
Class<EditText> cls = EditText.class;
Method method;
try {
activity.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
method = cls.getMethod("setShowSoftInputOnFocus", boolean.class);
method.setAccessible(true);
method.invoke(editText, false);
} catch (Exception e) {
// TODO: handle exception
}
}
/**
* 过滤输入框的空格
*
* @param editText
*/
public static void setEditTextInhibitInputSpace(EditText editText) {
InputFilter spaceFilter = new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (" ".equals(source)) {
return "";
} else {
return null;
}
}
};
InputFilter[] filters = editText.getFilters();
if (filters != null && filters.length > 0) {
InputFilter[] filterList = new InputFilter[filters.length + 1];
for (int i = 0; i < filters.length; i++) {
filterList[i] = filters[i];
}
filterList[filterList.length - 1] = spaceFilter;
editText.setFilters(filterList);
} else {
editText.setFilters(new InputFilter[]{spaceFilter});
}
}
/**
* 输入框删除逻辑 可以根据光标的选择进行删除了
*/
public static void deleteEditText(EditText editText) {
if (editText.hasFocus()) {
String content = editText.getText().toString().trim();
int index = editText.getSelectionStart() - 1;
if (content.length() > 0 && editText.getSelectionStart() != 0) {
StringBuffer sb = new StringBuffer(content);
sb.replace(index, index + 1, "");
editText.setText(sb.toString());
editText.setSelection(index);
sb.setLength(0);
}
}
}
/**
* 输入框的输入金额的逻辑 可以根据光标的选择输入;
*
* @param text 要插入的内容
*/
public static String inputAmountToEditText(EditText editText, String text) {
if (editText.hasFocus()) {
String num = editText.getText().toString().trim();
int indexSelectionStart = editText.getSelectionStart();
if (TextUtils.isEmpty(num)) {
if (StringUtils.hasAmountOverLimit(text)){
return "收款金额超过100,000限制";
} else {
editText.setText(text);
}
} else if (num.length() == indexSelectionStart) {
String content = num + text;
if (StringUtils.hasAmountOverLimit(content)){
return "收款金额超过100,000限制";
} else {
editText.setText(content);
}
} else {
// 判断下,如果输入已经达到了最大值,不做操作。否则会把已输入的内容吃掉
if (getMaxLength(editText) == num.length()) {
return "超过最长输入限制";
}
StringBuffer sb = new StringBuffer(num);
sb.replace(indexSelectionStart, indexSelectionStart + 1, text + sb.substring(indexSelectionStart, indexSelectionStart + 1));
String content = sb.toString();
if (StringUtils.hasAmountOverLimit(content)){
return "收款金额超过100,000限制";
} else {
editText.setText(content);
}
sb.setLength(0);
}
if (indexSelectionStart > num.length() - 1) {
editText.setSelection(editText.length());
} else {
editText.setSelection(indexSelectionStart + 1);
}
}
return "";
}
/**
* 输入框的输入逻辑 可以根据光标的选择输入;
*
* @param text 要插入的内容
*/
public static void inputEditText(EditText editText, String text) {
if (editText.hasFocus()) {
String num = editText.getText().toString().trim();
int index = editText.getSelectionStart();
if (TextUtils.isEmpty(num)) {
editText.setText(text);
} else if (num.length() == index) {
editText.setText(num + text);
} else {
// 判断下,如果输入已经达到了最大值,不做操作。否则会把已输入的内容吃掉
if (getMaxLength(editText) == num.length()) {
return;
}
StringBuffer sb = new StringBuffer(num);
sb.replace(index, index + 1, text + sb.substring(index, index + 1));
editText.setText(sb.toString());
sb.setLength(0);
}
if (index > num.length() - 1) {
editText.setSelection(editText.length());
} else {
editText.setSelection(index + 1);
}
}
}
/**
* 获取输入框的maxLength
*
* @param et
* @return
*/
public static int getMaxLength(EditText et) {
int length = 0;
try {
InputFilter[] inputFilters = et.getFilters();
for (InputFilter filter : inputFilters) {
Class<?> c = filter.getClass();
if (c.getName().equals("android.text.InputFilter$LengthFilter")) {
Field[] f = c.getDeclaredFields();
for (Field field : f) {
if (field.getName().equals("mMax")) {
field.setAccessible(true);
length = (Integer) field.get(filter);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return length;
}
/**
* 禁止输入框复制粘贴菜单
*
* @param editText
*/
@SuppressLint("ClickableViewAccessibility")
public static void disableEditTextCopyAndPaste(final EditText editText) {
try {
if (editText == null) {
return;
}
editText.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return true;
}
});
editText.setLongClickable(false);
editText.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// setInsertionDisabled when user touches the view
setInsertionDisabled(editText);
}
return false;
}
});
editText.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 boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private static void setInsertionDisabled(EditText editText) {
try {
Field editorField = TextView.class.getDeclaredField("mEditor");
editorField.setAccessible(true);
Object editorObject = editorField.get(editText);
// if this view supports insertion handles
Class editorClass = Class.forName("android.widget.Editor");
Field mInsertionControllerEnabledField = editorClass.getDeclaredField("mInsertionControllerEnabled");
mInsertionControllerEnabledField.setAccessible(true);
mInsertionControllerEnabledField.set(editorObject, false);
// if this view supports selection handles
Field mSelectionControllerEnabledField = editorClass.getDeclaredField("mSelectionControllerEnabled");
mSelectionControllerEnabledField.setAccessible(true);
mSelectionControllerEnabledField.set(editorObject, false);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.windfallsheng.inputamountwithkeyboard;
public class ResultWrapper {
private int code;
private boolean isSuccessful;
private String msg;
public ResultWrapper(int code, boolean isSuccessful, String msg) {
this.code = code;
this.isSuccessful = isSuccessful;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public boolean isSuccessful() {
return isSuccessful;
}
public void setSuccessful(boolean successful) {
isSuccessful = successful;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "ResultBean{" +
"code=" + code +
", isSuccessful=" + isSuccessful +
", msg='" + msg + '\'' +
'}';
}
}
package com.windfallsheng.inputamountwithkeyboard;
import android.os.Bundle;
import android.widget.FrameLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FrameLayout fragmentContainer = findViewById(R.id.fragment_container);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.fragment_container, CashFragment.newInstance(), CashFragment.class.getName())
.commitAllowingStateLoss();
}
}
总结
下载地址:https://download.csdn.net/download/Silence1515/40164786
实现过程并不复杂,主要是进行不同情况的业务判断,可根据自己的需要进行调整。