自定义数字键盘输入金额的控制方式

先上图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

说明

  在有自定义的输入键盘对 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
  实现过程并不复杂,主要是进行不同情况的业务判断,可根据自己的需要进行调整。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

windfallsheng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值