我试图显示带有小数值的EditText,但是我手机设置为英语时遇到了问题。我需要此EditText使用逗号作为小数分隔符,但Android键盘没有本地化小数分隔符的功能。所以我使用以下代码并且它无法正常工作。
import java.text.DecimalFormat;
import java.text.ParseException;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
public class NumberTextWatcher implements TextWatcher {
private DecimalFormat df;
private DecimalFormat dfnd;
private boolean hasFractionalPart;
private EditText et;
public NumberTextWatcher(EditText et)
{
Locale locale = new Locale("pt", "BR");
df = (DecimalFormat) NumberFormat.getNumberInstance(locale);
DecimalFormatSymbols.getInstance().setDecimalSeparator(',');
DecimalFormatSymbols.getInstance().setGroupingSeparator('.');
// THE ERROR HAPPENS IN THE NEXT LINE
df.applyPattern("#.###,##");
df.setDecimalSeparatorAlwaysShown(true);
dfnd = (DecimalFormat) NumberFormat.getNumberInstance(locale);
dfnd.applyPattern("#.###");
this.et = et;
hasFractionalPart = false;
}
@SuppressWarnings("unused")
private static final String TAG = "NumberTextWatcher";
@Override
public void afterTextChanged(Editable s)
{
et.removeTextChangedListener(this);
try {
int inilen, endlen;
inilen = et.getText().length();
String v = s.toString().replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), "");
Number n = df.parse(v);
int cp = et.getSelectionStart();
if (hasFractionalPart) {
et.setText(df.format(n));
} else {
et.setText(dfnd.format(n));
}
endlen = et.getText().length();
int sel = (cp + (endlen - inilen));
if (sel > 0 && sel <= et.getText().length()) {
et.setSelection(sel);
} else {
// place cursor at the end?
et.setSelection(et.getText().length() - 1);
}
} catch (NumberFormatException nfe) {
// do nothing?
} catch (ParseException e) {
// do nothing?
}
et.addTextChangedListener(this);
}
@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.toString().contains(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator())))
{
hasFractionalPart = true;
} else {
hasFractionalPart = false;
}
}
}
以下是例外:
10-26 16:59:23.100 16231-16231/com.br.myapp.debug E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.br.myapp.debug, PID: 16231 java.lang.IllegalArgumentException: syntax error: DecimalFormat::applyPattern failed: U_UNEXPECTED_TOKEN: #.###,## at libcore.icu.NativeDecimalFormat.applyPattern(NativeDecimalFormat.java:490) at libcore.icu.NativeDecimalFormat.applyPattern(NativeDecimalFormat.java:278) at java.text.DecimalFormat.applyPattern(DecimalFormat.java:589) at com.br.myapp.util.NumberTextWatcher.(NumberTextWatcher.java:27) at com.br.myapp.fragments.PriceDialogFragment.onCreateDialog(PriceDialogFragment.java:73) at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:307) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:942) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1484) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:450) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5679) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107) at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:1)
使用以下代码解决问题。它不是通用代码,但可以帮助其他人。
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
public class NumberTextWatcher implements TextWatcher {
private EditText mEditText;
public NumberTextWatcher(EditText editText) {
mEditText = editText;
}
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void afterTextChanged(Editable editable) {
mEditText.removeTextChangedListener(this);
try {
int inilen, endlen;
inilen = mEditText.getText().length();
String v = editable.toString().replace(".", ",");
// Se começar com vírgula, acrescento o zero automaticamente
if (inilen == 1 && v.equals(",")) {
v = "0,";
}
// Se já tiver vírgula, não deixo inserir novamente
if (v.indexOf(",") != v.lastIndexOf(",")) {
if (v.lastIndexOf(",") == v.length() - 1) {
v = v.substring(0, v.length() - 1);
}
}
// Se já tiver vírgula, não deixo ficar com 3 dígitos na parte decimal
int separatorPosition = v.indexOf(",");
String decimalPart = v.substring(separatorPosition + 1);
if (decimalPart.length() > 2) {
v = v.substring(0, v.length() - 1);
}
int cp = mEditText.getSelectionStart();
mEditText.setText(v);
endlen = mEditText.getText().length();
int sel = (cp + (endlen - inilen));
if (sel > 0 && sel <= mEditText.getText().length()) {
mEditText.setSelection(sel);
} else {
if (mEditText.getText().length() > 0) {
// place cursor at the end?
mEditText.setSelection(mEditText.getText().length() - 1);
}
}
} catch (NumberFormatException nfe) {
// do nothing?
}
mEditText.addTextChangedListener(this);
}
}