我在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;
}
};
这很好用。现在,我需要插入一个$
符号作为amount的前缀。所以我需要修改regx。我试过的是:-
"(([${0,1}][1-9]{1})([0-9]{0," + (maxDigitsBeforeDecimalPoint - 1) + "})?)?(\\.[0-9]{0," + maxDigitsAfterDecimalPoint + "})?"
但是当我输入TextWatcher
时,不允许我删除最后一个数字。
如果EditText
持有$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());
}
}
});
请让我知道这里的罪魁祸首。我对RegEx不好。
答案 0 :(得分:0)
将{{1}}放到最左边即可。所以最终的RegEx看起来像:-
“ [$]?(([[1-9] {1})([0-9] {0,” +(maxDigitsBeforeDecimalPoint-1)+“})?)?(\。[0-9] {0,“ + maxDigitsAfterDecimalPoint +”})?“
谢谢大家。
答案 1 :(得分:-1)
您可以使用以下库来实现此目的
https://github.com/BlacKCaT27/CurrencyEditText
You can use any type of currency with this
CurrencyEditText
CurrencyEditText是Android的EditText视图对象的扩展。该模块旨在在使用EditText字段从用户收集货币信息时提供易用性。
CurrencyEditText旨在与所有符合ISO-3166的语言环境一起使用(其中应包括Android船舶将提供的所有语言环境)。
如果您发现某个区域设置引起问题,请在问题跟踪器中打开一个问题。
更新的答案
如果上面的链接不起作用,请使用以下代码-
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>
现在您可以使用此edittext
<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" />
希望这可以满足您的要求,否则您可以根据要求编辑此代码。