安卓定制的EditText(货币格式) [英] Android custom EditText(currency format)

查看:165
本文介绍了安卓定制的EditText(货币格式)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有自定义的EditText将输入,也能够扭转其转换。然而它将始终使输入的小数,与输入后面1或2的值。现在我做一些计算应用程序,这需要整数。如何让这个自定义的EditText只取整数的输入和输出?

在code:

  @TargetApi(Build.VERSION_ codeS.GINGERBREAD)
公共类NumericEditText扩展的EditText {
    私人最终字符GROUPING_SEPARATOR = DecimalFormatSymbols.getInstance()getGroupingSeparator()。
    私人最终字符DECIMAL_SEPARATOR = DecimalFormatSymbols.getInstance()getDecimalSeparator()。
    私人最终字符串LEADING_ZERO_FILTER_REGEX =^ 0 +(?!$);

    私人字符串mDefaultText = NULL;
    私人串M previousText =;
    私人字符串mNumberFilterRegex ​​=[^ \\Ð\\+ DECIMAL_SEPARATOR +];

    / **
     *接口,当数值已被更改或清除通知监听器
     * /
    公共接口NumericValueWatcher {
        / **
         *当射击数值已更改
         *参数为newValue新的数值
         * /
        无效调用onChanged(双newValue)以;

        / **
         *当射击数值已被清除(文本字段为空)
         * /
        无效onCleared();
    }

    私人列表< NumericValueWatcher> mNumericListeners =新的ArrayList< NumericValueWatcher>();
    私人最终TextWatcher mTextWatcher =新TextWatcher(){
        私人布尔va​​lidateLock = FALSE;

        @覆盖
        公共无效afterTextChanged(编辑S){
            如果(validateLock){
                返回;
            }

            //有效的十进制数不应该超过2小数点分隔符
            如果(StringUtils.countMatches(s.toString(),将String.valueOf(DECIMAL_SEPARATOR))→1){
                validateLock = TRUE;
                的setText(M previousText); //取消变更并恢复到previous输入
                setSelection(M previousText.length());
                validateLock = FALSE;
                返回;
            }

            如果(s.length()== 0){
                handleNumericValueCleared();
                返回;
            }

            setTextInternal(格式(s.toString()));
            setSelection(gettext的()长度());
            handleNumericValueChanged();
        }

        @覆盖
        公共无效beforeTextChanged(CharSequence中,诠释开始,诠释计数,之后INT){
            // 没做什么
        }

        @覆盖
        公共无效onTextChanged(CharSequence中,诠释开始,诠释之前,诠释计数){
            // 没做什么
        }
    };

    私人无效handleNumericValueCleared(){
        米previousText =;
        对于(NumericValueWatcher听众:mNumericListeners){
            listener.onCleared();
        }
    }

    私人无效handleNumericValueChanged(){
        :M previousText =的getText()的toString();
        对于(NumericValueWatcher听众:mNumericListeners){
            listener.onChanged(getNumericValue());
        }
    }

    公共NumericEditText(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);

        addTextChangedListener(mTextWatcher);
        setOnClickListener(新View.OnClickListener(){
            @覆盖
            公共无效的onClick(视图v){
                //禁用移动光标
                setSelection(gettext的()长度());
            }
        });
    }

    / **
     *添加监听数值变化事件
     * @参数观察者监听器添加
     * /
    公共无效addNumericValueChangedListener(NumericValueWatcher观察者){
        mNumericListeners.add(守望者);
    }

    / **
     *删除所有听众数值变化事件
     * /
    公共无效removeAllNumericValueChangedListeners(){
        而(!mNumericListeners.isEmpty()){
            mNumericListeners.remove(0);
        }
    }

    / **
     *设置默认数值,它应如何显示,该值将是否被使用
     * {@link #clear}被称为
     *参数defaultNumericValue数值
     *对于数值@param defaultNumericFormat显示格式
     * /
    公共无效setDefaultNumericValue(双defaultNumericValue,最后弦乐defaultNumericFormat){
        mDefaultText =的String.Format(defaultNumericFormat,defaultNumericValue);
        setTextInternal(mDefaultText);
    }

    / **
     *清晰的文本字段,并将其与集合{@link #setDefaultNumericValue}默认值,如果更换
     * 任何
     * /
    公共无效清除(){
        setTextInternal(!?mDefaultText = NULL mDefaultText:);
        如果(mDefaultText!= NULL){
            handleNumericValueChanged();
        }
    }

    / **
     *返回由文本字段repesented数值
     返回:数值或{@link Double.NaN}如果不是数字
     * /
    公共双getNumericValue(){
        。字符串原=的getText()的toString()的replaceAll(mNumberFilterRegex,)。
        尝试 {
            返回NumberFormat.getInstance()解析(原件).doubleValue()。
        }赶上(ParseException的E){
            返回Double.NaN;
        }
    }

    / **
     *添加分组分隔符串
     * @参数原来原始的字符串,可能已经包含不正确的分组分隔符
     * @返回字符串正确的分组分隔符
     * /
    私人字符串格式(最后弦乐原件){
        最终的String []部分= original.split(\\+ DECIMAL_SEPARATOR,-1);
        串号=零件[0] //因为我们分裂了与极限-1总是会有至少1份
                .replaceAll(mNumberFilterRegex,)
                .replaceFirst(LEADING_ZERO_FILTER_REGEX,);

        //添加分组分隔符,需要扭转来回,因为Java的正则表达式不支持
        //从右到左匹配
        数= StringUtils.reverse(
                StringUtils.reverse(数).replaceAll(。({3}),$ 1+ GROUPING_SEPARATOR));
        //删除前导分组分隔符(如果有)
        数= StringUtils.removeStart(号码,将String.valueOf(GROUPING_SEPARATOR));

        //添加小数部分如果有的话
        如果(parts.length→1){
            数+ = DECIMAL_SEPARATOR +部分[1];
        }

        返回数;
    }

    / **
     *不触发数值更改显示的文本改变
     * @参数文本新文本申请
     * /
    私人无效setTextInternal(字符串文本){
        removeTextChangedListener(mTextWatcher);
        的setText(文本);
        addTextChangedListener(mTextWatcher);
    }
}
 

例如:

输入10000 这将是10,000瞬间, 输入10000.12 这将是10,000.12

我已经试过:

  INT输入2 = 0;
                。字符串文本2 = etpersen2.getText()的toString();
                如果(text2.length()大于0)
                     输入2 =的Integer.parseInt(文本2);
                串E =将String.valueOf(输入2);

                etresult.setText(+ E);
 

解决方案

使用 Math.round()要圆浮到最接近的整数。它返回一个int值,因此,使用类型转换(INT)是多余的。

 公共类测试{

   公共静态无效的主要(字符串的args []){
      双D = 100.675;
      双E = 100.500;
      浮动F = 100;
      浮G = 90F;

      的System.out.println(Math.round(d)条);
      的System.out.println(Math.round(e)条);
      的System.out.println(Math.round(F));
      的System.out.println(Math.round(G));
   }
}
 

I have custom EditText which will convert the input and also able to reverse it. However it will always make the input decimal, with 1 or 2 values behind the input. Right now i am making some calculation app, which need integer. How to make this custom EditText to just take integer input and output?

The code:

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public class NumericEditText extends EditText {
    private final char GROUPING_SEPARATOR = DecimalFormatSymbols.getInstance().getGroupingSeparator();
    private final char DECIMAL_SEPARATOR = DecimalFormatSymbols.getInstance().getDecimalSeparator();
    private final String LEADING_ZERO_FILTER_REGEX = "^0+(?!$)";

    private String mDefaultText = null;
    private String mPreviousText = "";
    private String mNumberFilterRegex = "[^\\d\\" + DECIMAL_SEPARATOR + "]";

    /**
     * Interface to notify listeners when numeric value has been changed or cleared
     */
    public interface NumericValueWatcher {
        /**
         * Fired when numeric value has been changed
         * @param newValue new numeric value
         */
        void onChanged(double newValue);

        /**
         * Fired when numeric value has been cleared (text field is empty)
         */
        void onCleared();
    }

    private List<NumericValueWatcher> mNumericListeners = new ArrayList<NumericValueWatcher>();
    private final TextWatcher mTextWatcher = new TextWatcher() {
        private boolean validateLock = false;

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

            // valid decimal number should not have more than 2 decimal separators
            if (StringUtils.countMatches(s.toString(), String.valueOf(DECIMAL_SEPARATOR)) > 1) {
                validateLock = true;
                setText(mPreviousText); // cancel change and revert to previous input
                setSelection(mPreviousText.length());
                validateLock = false;
                return;
            }

            if (s.length() == 0) {
                handleNumericValueCleared();
                return;
            }

            setTextInternal(format(s.toString()));
            setSelection(getText().length());
            handleNumericValueChanged();
        }

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

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // do nothing
        }
    };

    private void handleNumericValueCleared() {
        mPreviousText = "";
        for (NumericValueWatcher listener : mNumericListeners) {
            listener.onCleared();
        }
    }

    private void handleNumericValueChanged() {
        mPreviousText = getText().toString();
        for (NumericValueWatcher listener : mNumericListeners) {
            listener.onChanged(getNumericValue());
        }
    }

    public NumericEditText(Context context, AttributeSet attrs) {
        super(context, attrs);

        addTextChangedListener(mTextWatcher);
        setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // disable moving cursor
                setSelection(getText().length());
            }
        });
    }

    /**
     * Add listener for numeric value changed events
     * @param watcher   listener to add
     */
    public void addNumericValueChangedListener(NumericValueWatcher watcher) {
        mNumericListeners.add(watcher);
    }

    /**
     * Remove all listeners to numeric value changed events
     */
    public void removeAllNumericValueChangedListeners() {
        while (!mNumericListeners.isEmpty()) {
            mNumericListeners.remove(0);
        }
    }

    /**
     * Set default numeric value and how it should be displayed, this value will be used if
     * {@link #clear} is called
     * @param defaultNumericValue   numeric value
     * @param defaultNumericFormat  display format for numeric value
     */
    public void setDefaultNumericValue(double defaultNumericValue, final String defaultNumericFormat) {
        mDefaultText = String.format(defaultNumericFormat, defaultNumericValue);
        setTextInternal(mDefaultText);
    }

    /**
     * Clear text field and replace it with default value set in {@link #setDefaultNumericValue} if
     * any
     */
    public void clear() {
        setTextInternal(mDefaultText != null ? mDefaultText : "");
        if (mDefaultText != null) {
            handleNumericValueChanged();
        }
    }

    /**
     * Return numeric value repesented by the text field
     * @return  numeric value or {@link Double.NaN} if not a number
     */
    public double getNumericValue() {
        String original = getText().toString().replaceAll(mNumberFilterRegex, "");
        try {
            return NumberFormat.getInstance().parse(original).doubleValue();
        } catch (ParseException e) {
            return Double.NaN;
        }
    }

    /**
     * Add grouping separators to string
     * @param original  original string, may already contains incorrect grouping separators
     * @return  string with correct grouping separators
     */
    private String format(final String original) {
        final String[] parts = original.split("\\" + DECIMAL_SEPARATOR, -1);
        String number = parts[0] // since we split with limit -1 there will always be at least 1 part
                .replaceAll(mNumberFilterRegex, "")
                .replaceFirst(LEADING_ZERO_FILTER_REGEX, "");

        // add grouping separators, need to reverse back and forth since Java regex does not support
        // right to left matching
        number = StringUtils.reverse(
                StringUtils.reverse(number).replaceAll("(.{3})", "$1" + GROUPING_SEPARATOR));
        // remove leading grouping separator if any
        number = StringUtils.removeStart(number, String.valueOf(GROUPING_SEPARATOR));

        // add fraction part if any
        if (parts.length > 1) {
            number += DECIMAL_SEPARATOR + parts[1];
        }

        return number;
    }

    /**
     * Change display text without triggering numeric value changed
     * @param text  new text to apply
     */
    private void setTextInternal(String text) {
        removeTextChangedListener(mTextWatcher);
        setText(text);
        addTextChangedListener(mTextWatcher);
    }
}

Example:

input 10000 it will be 10,000 in an instant, input 10000.12 it will be 10,000.12

what i've tried:

                int input2 = 0;
                String text2 = etpersen2.getText().toString();
                if (text2.length() > 0)
                     input2 = Integer.parseInt(text2);
                String e = String.valueOf(input2);

                etresult.setText("" + e);

解决方案

Using Math.round() should round the float to the nearest whole number. It returns an int value so typecasting using (int) is redundant.

public class Test{ 

   public static void main(String args[]){
      double d = 100.675;
      double e = 100.500;
      float f = 100;
      float g = 90f;

      System.out.println(Math.round(d));
      System.out.println(Math.round(e)); 
      System.out.println(Math.round(f)); 
      System.out.println(Math.round(g)); 
   }
}

这篇关于安卓定制的EditText(货币格式)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆