Android自定义EditText(货币格式)

2024-01-13

我有自定义的 EditText ,它可以转换输入,也可以反转它。但是,它始终会使输入成为十进制,并在输入后面带有 1 或 2 个值。现在我正在制作一些计算应用程序,它需要整数。如何使这个自定义 EditText 仅接受整数输入和输出?

代码:

@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:

输入10000 瞬间就到10000了 输入10000.12 将会是 10,000.12

我尝试过的:

                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()应该将浮点数四舍五入到最接近的整数。它返回一个 int 值,因此使用类型转换(int)是多余的。

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)); 
   }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android自定义EditText(货币格式) 的相关文章

  • 现实世界中的 JavaCard 3?

    我目前正在从事我的文凭工作 部分工作包括开发JavaCard常规小程序SIM牌 第一个选项是使用JavaCard2 X API并使用APDU与小程序通信的命令 这可能非常棘手 因为我需要为 android 开发客户端应用程序 它将与这个小程
  • ListView 和 CursorAdapter 对于大量数据的性能问题

    我在 sqlite 表中有大约 4k 行 表有 7 列 我用自己的 CursorAdapter 创建了工作 ListView 查询是这样的SELECT FROM table ORDER BY column DESC 表有第一列 id INT
  • 即使成功固定后,ParseQuery 在从本地数据存储查询时也给出 0 个对象

    我正在使用 parse com 的 Android SDK 并且遇到了一个特殊的问题 从片段的 onCreate 中 从服务器获取一个对象 Pin it 从本地数据存储中获取对象 以下是 onCreate 中的代码片段 ParseObjec
  • 浮动操作按钮动画

    当 fab 出现时 它使用动画中的比例进行动画处理 当它隐藏时 它使用向外扩展动画 因此 它是一个缩小和缩小的动画 这个动画要怎么制作呢 从 Zielony 的回答来看 我完全按照我想要的方式制作了它 下面是正确应用效果的代码 scale
  • 在 Android 中使用 PhoneGap 打开 PDF

    我需要打开一个位于 url 中的 PDF 文件 我需要用 PDF 查看器打开它 有可能的 谢谢大家 此致 我建议使用儿童浏览器插件 https build phonegap com blog childbrowser plugin并使用 G
  • 清除未接来电并清除 Android 栏中的通知

    使用此代码 我设法将所有未接来电标记为已读 ContentValues values new ContentValues values put Calls NEW 0 if android os Build VERSION SDK INT
  • 使用书法库的某些活动使用不同的字体

    我在用书法 https github com chrisjenx Calligraphy在我的应用程序中使用自定义字体的库 我使用默认字体为整个应用程序设置了自定义字体CalligraphyConfig in my Application类
  • 将倒计时器从 10 秒改为 1 秒

    我有一个倒计时器 它以 1 秒的增量从 10000 毫秒倒计时到 0 毫秒 以使按钮在 10 秒后可单击 尽管计时器是准确的并且按照代码的说明执行操作 但我想更改秒的表示方式 但我不知道如何更改 java void startTimer c
  • 如何让文字发光?

    我们可以将发光效果应用于任何文本 如下所示 Updated Please also tell me what things i need to create something like this 我需要为此使用特殊字体吗 如何使用以下命令
  • 使用 android-async-http (loopj) 发布 JSON/XML

    我在用android async http http loopj com android async http 并且真的很喜欢它 我在发布数据时遇到了问题 我必须按照以下格式将数据发布到 API
  • 语音识别和文本转语音

    我想开发一个实现语音识别的应用程序 然后使用文本到语音引擎实现文本到语音 我发布了下面的代码 我使用两个按钮和一个列表视图 一个按钮用于语音识别 另一个按钮用于文本转语音 列表视图用于两者 首先在列表视图中发布语音识别的结果 然后应用程序将
  • AWS Cognito-获取带有ID的用户信息

    有没有什么方法可以获取 AWS Cognito 池 在 Android 上 中未登录的用户的信息 并知道他的 ID 我尝试了该代码 AppHelper getPool getUser username getDetailsInBackgro
  • 无法将图像从 url 存储到 SD 卡

    我想将图像存储在 mnt sdcard 中 package com Downld file frm net import java io BufferedInputStream import java io File import java
  • PhoneGap文件传输错误1、哪里写FileTransfers?

    相关 https stackoverflow com questions 21044197 download file and store them locally in sdcard using phonegapbuild https s
  • Android 应用程序中通过 VideoView 将正在播放的视频静音

    我想在我的 Android 应用程序中将 VideoView 正在播放的视频静音 我在 VideoView 类中找不到任何方法来执行此操作 知道如何做到这一点吗 我在 MediaPlayer 类中找到了一个方法 setVolume 但我无法
  • 对特定路径使用 Intent.ACTION_PICK

    我正在尝试使用 Android 图库来选择图像 为此目的启动画廊很容易 Intent photoPickerIntent new Intent Intent ACTION PICK photoPickerIntent setType ima
  • 如何以编程方式将 Android 设备连接到“WPA2 PSK”安全 WiFi 热点网络?

    在我的 Android 应用程序中 我尝试将我的 Android 设备连接到 WPA2 PSK 安全连接 经过大量搜索后 我编写了以下代码 if securityMode equalsIgnoreCase WPA2 WPA2 wifiCon
  • 同一活动中的多个日期选择器

    我对 Android 平台完全陌生 在学习开发过程的同时一直在构建应用程序 目前 我正在开展一项活动 需要部署 2 个日期选择器 一个是 开始日期 另一个是 结束日期 我一直在关注 Android 开发者页面上的 DatePicker 教程
  • Firebase 附加权限。是否要求用户接受

    我目前正在致力于将 Firebase Analytics 集成到我的 Android 应用程序中 我遇到的问题是 Firebase 添加了一些新权限 这些权限是 permission WAKE LOCK com google android
  • 当应用程序在 Android 中首次启动时,仅显示一次消息对话框

    我在android中开发了一个应用程序 其中一个重要的要求是仅在应用程序第一次运行时显示语言支持的消息对话框 然后每次用户再次运行应用程序时它都会消失 我 我尝试过使用共享首选项 但没有成功 还有其他方法吗 在 onCreate 处理程序中

随机推荐

  • 使用可变引用迭代递归结构并返回最后一个有效引用

    我正在尝试递归节点结构 修改它们 然后返回最后一个Node我能做到的 我使用循环中的可变引用解决了问题非词汇生命周期 RFC 中的示例 https github com rust lang rfcs blob master text 209
  • 从命令行批量导出组织模式文件

    假设我在某个目录中有几个org mode files foo1 org foo2 org等等 我想要一个脚本 也许是一个 makefile 我可以调用类似的东西 generate pdfs and foo1 pdf foo2 pdf等都会生
  • 如何旋转 igraph 网络图?

    我正在尝试旋转基于 R 包的 igraph 网络图 在 igraph 指南中没有足够的解释如何使用 R 代码 tk rotate tkp id degree NULL rad NULL 对于 R 包igraph根据文档 tk rotate
  • Java Swing:扩展 DefaultComboBoxModel 并重写方法

    我正在使用DefaultComboBoxModel显示客户列表JComboBox 该列表当前仅显示他们的名字 我还想为每个客户提供参考DefaultComboBoxModel这样 当选择名称时 它还保存对真实客户对象的引用 为了实现这一目标
  • 无效的请求状态:oauth2 Flask

    我使用以下代码使用 oauth 2 0 进行身份验证 oauth2 init app app scopes email profile authorize callback request user info 路线如下 app route
  • 如果测试失败则使 docker 构建失败

    Dockerfile FROM node carbon WORKDIR usr src app COPY package json RUN npm install RUN npm install gulp g COPY run gulp b
  • Java 正则表达式库是否针对任何字符 .* 进行优化?

    我有一个用于匹配正则表达式的包装类 显然 您将正则表达式编译为Pattern像这样 Pattern pattern Pattern compile regex 但假设我用了一个 指定任意数量的字符 所以它基本上是一个通配符 Pattern
  • 如何在 Resharper 4.5 中使用 bdd 命名样式?

    我刚刚升级到 Resharper 4 5 现在看到我所有的 BDDish 测试方法都被标记为不符合命名标准 我的命名约定是这样的 public void Something ShouldHaveThisResult Resharper 不喜
  • 如何在 flutter 应用程序中集成 yolo-v3 自定义对象检测器?

    我开发了 flutter 应用程序并yolov3自定义对象检测器 两个模块都是独立的 现在我想将这些模块合并到一个项目中 但无法弄清楚如何在我的 flutter 应用程序中使用自定义对象检测器的训练权重 有人可以帮我完成这个集成吗 不知道是
  • 在 Typescript 中是否必须使用函数的结果值说明符?

    我想指定函数的返回值必须使用打字稿来使用 C 中有一个属性 nodiscard Typescript 中有类似的属性吗 Example function setSomeFields someThing MyClass const other
  • 如何获取JQuery中复选框的值?

    我正在使用 JQuery 来发布表单 我无法从该字段获取正确的值
  • Keras 序列模型的多个嵌入层

    我正在使用 Keras 张量流后端 并且想知道如何将多个嵌入层添加到 Keras 顺序模型中 更具体地说 我的数据集中有几列具有分类值 我考虑过使用 one hot 编码 但确定分类项的数量有数百个 导致一组大且过于稀疏的列 在寻找解决方案
  • 如何在Redis中进行搜索?

    在 MySQL 中我有一个表名为 cities其中包括 2 列 name and population 然后我得到搜索结果 SELECT FROM cities WHERE name LIKE Bu ORDER by population
  • com.parse.ParseException:java.lang.IllegalStateException:尝试查找不存在的uuid

    我在我的应用程序中使用 parse android SDK 这是我的登录活动 public class LoginActivity extends Activity EditText username password Button log
  • OpenCV - 去除图像中的噪声

    我这里有一张带有表格的图像 在右侧的列中 背景充满了噪音 如何检测有噪声的区域 我只想在有噪音的部分应用某种过滤器 因为我需要对其进行 OCR 任何类型的过滤器都会降低整体识别率 什么样的滤波器最能去除图像中的背景噪声 正如我所说 我需要对
  • 如何取消 RXJS Effects 中发出的角度 http 请求

    我想取消 Angular 8 中 RXJS 效果中发出的 http 请求 Effect getReport this action pipe ofType ActionTypes GET WIDGET map toPayload merge
  • 在访问者模式中使用accept()

    我正在考虑使用访客模式 我看到的一些示例建议在每个 Element 子类中使用 Accept Visitor 函数 该函数的想法只是为了让访问者可以访问包含多态类型的集合吗 在这段代码中 我使用访问者进行两种类型的累加 并且不需要accep
  • java的内存分配

    问题 我已设置 Xms512m 和 Xmx1024m 来运行应用程序 实习生使用 C 本机层执行其他操作 运行应用程序时出现 OutOfMemory 异常 我需要知道 C 使用哪个内存 即来自分配的内存 Xms512m 和 Xmx1024m
  • PHPUnit 分段错误 11

    我今天早上尝试运行 PHPUnit 它产生了 Segmentation Failure 11 错误 使用命令phpunit unit 如果我使用 Selenium 在功能测试中运行 PHPUnit 那么一切都会正常 只有单元测试受到影响 我
  • Android自定义EditText(货币格式)

    我有自定义的 EditText 它可以转换输入 也可以反转它 但是 它始终会使输入成为十进制 并在输入后面带有 1 或 2 个值 现在我正在制作一些计算应用程序 它需要整数 如何使这个自定义 EditText 仅接受整数输入和输出 代码 T