代码之家  ›  专栏  ›  技术社区  ›  Diaz diaz

正则表达式以允许带有numberDecimal的$符号

  •  0
  • Diaz diaz  · 技术社区  · 6 年前

    InputFilter EditText 输入数量。

    InputFilter filter = new InputFilter() {
            final int maxDigitsBeforeDecimalPoint = 5;
            final int maxDigitsAfterDecimalPoint = 2;
            @Override
            public CharSequence filter(CharSequence source, int start, int end,
                                       Spanned dest, int dstart, int dend) {
                StringBuilder builder = new StringBuilder(dest);
                builder.replace(dstart, dend, source
                        .subSequence(start, end).toString());
                if (!builder.toString().matches(
                        "(([1-9]{1})([0-9]{0," + (maxDigitsBeforeDecimalPoint - 1) + "})?)?(\\.[0-9]{0," + maxDigitsAfterDecimalPoint + "})?"
                )) {
                    if (source.length() == 0)
                        return dest.subSequence(dstart, dend);
                    return "";
                }
                return null;
            }
        };
    

    这很管用。现在我需要插入一个 $ 作为金额的前缀签名。所以我需要修改regx。我试过的是:-

    "(([${0,1}][1-9]{1})([0-9]{0," + (maxDigitsBeforeDecimalPoint - 1) + "})?)?(\\.[0-9]{0," + maxDigitsAfterDecimalPoint + "})?"
    

    TextWatcher 它不允许我删除最后一个号码。 编辑文本 持有 $3 那就不删除了。

    edtAmount.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }
    
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }
            @Override
            public void afterTextChanged(Editable editable) {
                String input = editable.toString();
                if (TextUtils.isEmpty(input))
                    return;
                if (input.equals("$")) {
                    edtAmount.setText("");
                    return;
                }
                if(!input.startsWith("$")){
                    edtAmount.setText("$" + input);
                    edtAmount.setSelection(edtAmount.getText().toString().length());
                }
            }
        });
    

    2 回复  |  直到 6 年前
        1
  •  0
  •   Diaz diaz    6 年前

    [$]? 在最左边工作。最后的正则表达式看起来像:-

    “[$]?(([1-9]{1})([0-9]{0,”+(MaxDigitBeforeDecimalPoint-1)+“})?)?(\.[0-9]{0,”+MaxDigitAfterDecimalPoint+“})?”

        2
  •  -1
  •   Dheeraj Singh Bhadoria    6 年前

    https://github.com/BlacKCaT27/CurrencyEditText

    You can use any type of currency with this

    CurrencyEditText是Android的EditText视图对象的扩展。它是一个模块,用于在使用EditText字段从用户收集货币信息时提供易用性。

    如果发现某个区域设置导致了问题,请在问题跟踪程序中打开问题。

    如果上面的链接不起作用,请使用以下代码-

    import android.content.Context;
    import android.content.res.TypedArray;
    import android.os.Build;
    import android.text.Editable;
    import android.text.InputType;
    import android.text.TextWatcher;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.widget.EditText;
    
    import java.text.DecimalFormat;
    import java.text.DecimalFormatSymbols;
    import java.text.ParseException;
    import java.util.Currency;
    import java.util.Locale;
    
    
    public class CurrencyEditText extends EditText {
       private char mGroupDivider;
       private char mMonetaryDivider;
       private String mLocale = "";
       private boolean mShowSymbol;
    
       private char groupDivider;
       private char monetaryDivider;
    
       private Locale locale;
       private DecimalFormat numberFormat;
    
       private int fractionDigit;
       private String currencySymbol;
    
       public CurrencyEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
    
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.currencyEditText, 0, 0);
    
        try {
            if (a.getString(R.styleable.currencyEditText_groupDivider) != null) {
                this.mGroupDivider = a.getString(R.styleable.currencyEditText_groupDivider).charAt(0);
                this.groupDivider = mGroupDivider;
            }
    
            if (a.getString(R.styleable.currencyEditText_monetaryDivider) != null) {
                this.mMonetaryDivider = a.getString(R.styleable.currencyEditText_monetaryDivider).charAt(0);
                this.monetaryDivider = mMonetaryDivider;
            }
    
            if (a.getString(R.styleable.currencyEditText_locale) == null)
                this.locale = getDefaultLocale();
            else this.mLocale = a.getString(R.styleable.currencyEditText_locale);
    
            if (a.getString(R.styleable.currencyEditText_showSymbol) != null)
                this.mShowSymbol = a.getBoolean(R.styleable.currencyEditText_showSymbol, false);
    
            if (mLocale.equals("")) {
                locale = getDefaultLocale();
            } else {
                if (mLocale.contains("-"))
                    mLocale = mLocale.replace("-", "_");
    
                String[] l = mLocale.split("_");
                if (l.length > 1) {
                    locale = new Locale(l[0], l[1]);
                } else {
                    locale = new Locale("", mLocale);
                }
            }
    
            initSettings();
        } finally {
            a.recycle();
        }
    
        this.addTextChangedListener(onTextChangeListener);
    }
    
    /***
     * If user does not provide a valid locale it throws IllegalArgumentException.
     * 
     * If throws an IllegalArgumentException the locale sets to default locale
     */
    private void initSettings() {
        boolean success = false;
        while (!success) {
            try {
                fractionDigit = Currency.getInstance(locale).getDefaultFractionDigits();
    
                DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locale);
                if (mGroupDivider > 0)
                    symbols.setGroupingSeparator(mGroupDivider);
                groupDivider = symbols.getGroupingSeparator();
    
                if (mMonetaryDivider > 0)
                    symbols.setMonetaryDecimalSeparator(mMonetaryDivider);
                monetaryDivider = symbols.getMonetaryDecimalSeparator();
    
                currencySymbol = symbols.getCurrencySymbol();
    
                DecimalFormat df = (DecimalFormat) DecimalFormat.getCurrencyInstance(locale);
                numberFormat = new DecimalFormat(df.toPattern(), symbols);
    
                success = true;
            } catch (IllegalArgumentException e) {
                Log.e(getClass().getCanonicalName(), e.getMessage());
                locale = getDefaultLocale();
            }
        }
    }
    
    private Locale getDefaultLocale() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
            return getContext().getResources().getConfiguration().getLocales().get(0);
        else
            return getContext().getResources().getConfiguration().locale;
    }
    
    /***
     *It resets text currently displayed If user changes separators or locale etc.
     */
    private void resetText() {
        String s = getText().toString();
        if (s.isEmpty()) {
            initSettings();
            return;
        }
    
        s = s.replace(groupDivider, '\u0020').replace(monetaryDivider, '\u0020')
                .replace(".", "").replace(" ", "")
                .replace(currencySymbol, "").trim();
        try {
            initSettings();
            s = format(s);
            removeTextChangedListener(onTextChangeListener);
            setText(s);
            setSelection(s.length());
            addTextChangedListener(onTextChangeListener);
        } catch (ParseException e) {
            Log.e(getClass().getCanonicalName(), e.getMessage());
        }
    }
    
    private TextWatcher onTextChangeListener = new TextWatcher() {
    
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
        }
    
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (s.length() == 0)
                return;
    
            removeTextChangedListener(this);
    
            /***
             * Clear input to get clean text before format
             * '\u0020' is empty character
             */
            String text = s.toString();
            text = text.replace(groupDivider, '\u0020').replace(monetaryDivider, '\u0020')
                    .replace(".", "").replace(" ", "")
                    .replace(currencySymbol, "").trim();
            try {
                text = format(text);
            } catch (ParseException e) {
                Log.e(getClass().getCanonicalName(), e.getMessage());
            }
    
            setText(text);
            setSelection(text.length());
    
            addTextChangedListener(this);
        }
    
        @Override
        public void afterTextChanged(Editable s) {
    
        }
    };
    
    private String format(String text) throws ParseException {
        if (mShowSymbol)
            return numberFormat.format(Double.parseDouble(text) / Math.pow(10, fractionDigit));
        else
            return numberFormat.format(Double.parseDouble(text) / Math.pow(10, fractionDigit)).replace(currencySymbol, "");
    }
    
    /***
     * returns the decimal separator for current locale
     * for example; input value 1,234.56
     *              returns ','
     *
     * @return decimal separator char
     */
    public char getGroupDivider() {
        return groupDivider;
    }
    
    /***
     * sets how to divide decimal value and fractions
     * for example; If you want formatting like this
     *              for input value 1,234.56
     *              set ','
     * @param groupDivider char
     */
    public void setGroupDivider(char groupDivider) {
        this.mGroupDivider = groupDivider;
        resetText();
    }
    
    /***
     * returns the monetary separator for current locale
     * for example; input value 1,234.56
     *              returns '.'
     *
     * @return monetary separator char
     */
    public char getMonetaryDivider() {
        return monetaryDivider;
    }
    
    /***
     * sets how to divide decimal value and fractions
     * for example; If you want formatting like this
     *              for input value 1,234.56
     *              set '.'
     * @param monetaryDivider char
     */
    public void setMonetaryDivider(char monetaryDivider) {
        this.mMonetaryDivider = monetaryDivider;
        resetText();
    }
    
    /***
     *
     * @return current locale
     */
    public Locale getLocale() {
        return locale;
    }
    
    /***
     * Sets locale which desired currency format
     *
     * @param locale
     */
    public void setLocale(Locale locale) {
        this.locale = locale;
        resetText();
    }
    
    /**
     *
     * @return true if currency symbol of current locale is showing
     */
    public boolean showSymbol() {
        return this.mShowSymbol;
    }
    
    /***
     * Sets if currency symbol of current locale shows
     *
     * @param showSymbol
     */
    public void showSymbol(boolean showSymbol) {
        this.mShowSymbol = showSymbol;
        resetText();
    }
    
    /**
     *
     *  @return double value for current text
     */
    public double getCurrencyDouble() throws ParseException {
        String text = getText().toString();
        text = text.replace(groupDivider, '\u0020').replace(monetaryDivider, '\u0020')
                .replace(".", "").replace(" ", "")
                .replace(currencySymbol, "").trim();
    
        if (showSymbol())
            return Double.parseDouble(text.replace(currencySymbol, "")) / Math.pow(10, fractionDigit);
        else return Double.parseDouble(text) / Math.pow(10, fractionDigit);
    }
    
    /**
     *
     *  @return String value for current text
     */
    public String getCurrencyText() throws ParseException {
        if (showSymbol())
            return getText().toString().replace(currencySymbol, "");
    }
    

    }

    此文件还需要attrs.xml将此文件放在values文件夹中

      <?xml version="1.0" encoding="utf-8"?>
      <resources>
      <declare-styleable name="currencyEditText">
         <attr name="groupDivider" format="string" />
         <attr name="monetaryDivider" format="string" />
         <attr name="locale" format="string" />
         <attr name="showSymbol" format="boolean" />
     </declare-styleable>
     </resources>
    

    现在你可以用这个编辑文本了

    <CurrencyEditText
        android:id="@+id/edt_currency"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="numberDecimal"
        android:textColor="@android:color/black"
        app:groupDivider="."
        app:monetaryDivider=","
        app:locale="en_US"
        app:showSymbol="true" />