android 货币格式化,格式化货币输入editText的更好方法?

本文介绍了一个自定义的EditText组件——CurrencyEditText,用于处理货币格式的输入。该组件限制输入长度,自动格式化数字,并在失去焦点时处理空值情况。它使用了TextWatcher监听输入变化,通过DecimalFormat进行格式化,确保在所有语言环境下都能正确显示货币格式。在XML布局文件中可以方便地使用此组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是我的习惯 CurrencyEditText

import android.content.Context;import android.graphics.Rect;import android.text.Editable;import android.text.InputFilter;import android.text.InputType;import android.text.TextWatcher;

import android.util.AttributeSet;import android.widget.EditText;import java.math.BigDecimal;import java.math.RoundingMode;

import java.text.DecimalFormat;import java.text.DecimalFormatSymbols;

import java.util.Locale;

/**

* Some note

*

Always use locale US instead of default to make DecimalFormat work well in all language

*/

public class CurrencyEditText extends android.support.v7.widget.AppCompatEditText {

private static String prefix = "VND ";

private static final int MAX_LENGTH = 20;

private static final int MAX_DECIMAL = 3;

private CurrencyTextWatcher currencyTextWatcher = new CurrencyTextWatcher(this, prefix);

public CurrencyEditText(Context context) {

this(context, null);

}

public CurrencyEditText(Context context, AttributeSet attrs) {

this(context, attrs, android.support.v7.appcompat.R.attr.editTextStyle);

}

public CurrencyEditText(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

this.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);

this.setHint(prefix);

this.setFilters(new InputFilter[] { new InputFilter.LengthFilter(MAX_LENGTH) });

}

@Override

protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {

super.onFocusChanged(focused, direction, previouslyFocusedRect);

if (focused) {

this.addTextChangedListener(currencyTextWatcher);

} else {

this.removeTextChangedListener(currencyTextWatcher);

}

handleCaseCurrencyEmpty(focused);

}

/**

* When currency empty

* + When focus EditText, set the default text = prefix (ex: VND)

* + When EditText lose focus, set the default text = "", EditText will display hint (ex:VND)

*/

private void handleCaseCurrencyEmpty(boolean focused) {

if (focused) {

if (getText().toString().isEmpty()) {

setText(prefix);

}

} else {

if (getText().toString().equals(prefix)) {

setText("");

}

}

}

private static class CurrencyTextWatcher implements TextWatcher {

private final EditText editText;

private String previousCleanString;

private String prefix;

CurrencyTextWatcher(EditText editText, String prefix) {

this.editText = editText;

this.prefix = prefix;

}

@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

}

@Override

public void afterTextChanged(Editable editable) {

String str = editable.toString();

if (str.length() < prefix.length()) {

editText.setText(prefix);

editText.setSelection(prefix.length());

return;

}

if (str.equals(prefix)) {

return;

}

// cleanString this the string which not contain prefix and ,

String cleanString = str.replace(prefix, "").replaceAll("[,]", "");

// for prevent afterTextChanged recursive call

if (cleanString.equals(previousCleanString) || cleanString.isEmpty()) {

return;

}

previousCleanString = cleanString;

String formattedString;

if (cleanString.contains(".")) {

formattedString = formatDecimal(cleanString);

} else {

formattedString = formatInteger(cleanString);

}

editText.removeTextChangedListener(this); // Remove listener

editText.setText(formattedString);

handleSelection();

editText.addTextChangedListener(this); // Add back the listener

}

private String formatInteger(String str) {

BigDecimal parsed = new BigDecimal(str);

DecimalFormat formatter =

new DecimalFormat(prefix + "#,###", new DecimalFormatSymbols(Locale.US));

return formatter.format(parsed);

}

private String formatDecimal(String str) {

if (str.equals(".")) {

return prefix + ".";

}

BigDecimal parsed = new BigDecimal(str);

// example pattern VND #,###.00

DecimalFormat formatter = new DecimalFormat(prefix + "#,###." + getDecimalPattern(str),

new DecimalFormatSymbols(Locale.US));

formatter.setRoundingMode(RoundingMode.DOWN);

return formatter.format(parsed);

}

/**

* It will return suitable pattern for format decimal

* For example: 10.2 -> return 0 | 10.23 -> return 00, | 10.235 -> return 000

*/

private String getDecimalPattern(String str) {

int decimalCount = str.length() - str.indexOf(".") - 1;

StringBuilder decimalPattern = new StringBuilder();

for (int i = 0; i < decimalCount && i < MAX_DECIMAL; i++) {

decimalPattern.append("0");

}

return decimalPattern.toString();

}

private void handleSelection() {

if (editText.getText().length() <= MAX_LENGTH) {

editText.setSelection(editText.getText().length());

} else {

editText.setSelection(MAX_LENGTH);

}

}

}

}

在XML中使用它,例如

<...currencyedittext>

android:layout_width="match_parent"

android:layout_height="wrap_content"

/>

您应该在下面编辑2个常量以适合您的项目

private static String prefix = "VND ";

private static final int MAX_DECIMAL = 3;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值