我想使用EditText
自动实时格式化用户输入的内容,例如,它将1000000转换为1,000,000
我尝试了Android Money Input with fixed decimal,但是在设置文字时,应用崩溃了
EditText etMoney;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etMoney = (EditText)findViewById(R.id.etMoney);
etMoney.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) {
etMoney.setText(currencyFormat(etMoney.getText().toString()));
}
@Override
public void afterTextChanged(Editable editable) {
}
});
}
public static String currencyFormat(String amount) {
DecimalFormat formatter = new DecimalFormat("###,###,###");
return formatter.format(Double.parseDouble(amount));
}
我想要的输出是直接转换为EditText的实时转换器,但是一旦我在EditText
中键入内容,应用就会崩溃。
崩溃日志:
06-20 15:19:57.453 1699-1715/system_process E/ActivityManager: ANR in com.hassilproject.myapplication (com.hassilproject.myapplication/.MainActivity)
PID: 2521
Reason: Input dispatching timed out (Waiting to send key event because the focused window has not finished processing all of the input events that were previously delivered to it. Outbound queue length: 0. Wait queue length: 1.)
答案 0 :(得分:0)
更改此代码
etMoney.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) {
etMoney.setText(currencyFormat(editable.toString()));
}
});
答案 1 :(得分:0)
尝试一下,我创建了一个自定义视图来输入货币。使用currency()
方法在EditText中获取值。
class CurrencyInput(context: Context, attributeSet: AttributeSet) : TextInputEditText(context, attributeSet) {
private val currencyTextWatcher = CurrencyWatcher()
override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
super.onFocusChanged(focused, direction, previouslyFocusedRect)
if (focused) addTextChangedListener(currencyTextWatcher) else removeTextChangedListener(currencyTextWatcher)
}
fun currency(): Long = currencyTextWatcher.amount
private fun Long.toDecimalStr(): String = decimalFormatter().format(this)
inner class CurrencyWatcher : TextWatcher {
var amount = 0L
var amountDecimal = ""
override fun afterTextChanged(editable: Editable?) {
editable?.toString()?.run {
when {
equals("") -> {
amount = 0
amountDecimal = "0"
}
else -> {
amount = replace(",", "").replace(".", "").toLong()
amountDecimal = if (amount >= 1000) amount.toDecimalStr() else amount.toString()
}
}
this@CurrencyInput.apply {
removeTextChangedListener(this@CurrencyWatcher)
amount.let {
setText(amountDecimal)
setSelection(amountDecimal.length)
}
addTextChangedListener(this@CurrencyWatcher)
}
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { }
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { }
}
}
在布局中使用CurrencyInput时,请用您的包裹名称替换
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="7dp"
android:hint="Currency"
app:endIconMode="clear_text">
<com.package.CurrencyInput
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"/>
</com.google.android.material.textfield.TextInputLayout>
答案 2 :(得分:0)
我希望这对您有用。
etMoney.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) {
etMoney.removeTextChangedListener(this);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
try {
if (!editable.toString().equalsIgnoreCase("")) {
etMoney.setText("" + currencyFormat(editable.toString()));
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}, 4000); //after 4 second it will update to UI.
etMoney.addTextChangedListener(this);
}
});
下面给出的货币格式方法
public String currencyFormat(String amount) {
return new DecimalFormat("###,###,###").format(Double.parseDouble(amount));
}
答案 3 :(得分:0)
//创建方法
private TextWatcher onTextChangedListener() {
return 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) {
}
@Override
public void afterTextChanged(Editable s) {
editText.removeTextChangedListener(this);
try {
String originalString = s.toString();
Long longval;
if (originalString.contains(",")) {
originalString = originalString.replaceAll(",", "");
}
longval = Long.parseLong(originalString);
DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);
formatter.applyPattern("#,###,###,###");
String formattedString = formatter.format(longval);
//setting text after format to EditText
editText.setText(formattedString);
editText.setSelection(editText.getText().length());
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
editText.addTextChangedListener(this);
}
};
}
//调用方法
editText.addTextChangedListener(onTextChangedListener());
答案 4 :(得分:0)
每次更改EditText的文本时,都会调用TextWatcher方法。因此,您必须设置标志以指示更改源。还有TextWatcher回调方法。检查指示标志以避免无限循环。
etMoney.addTextChangedListener(new TextWatcher() {
private boolean changedByFormatText = false;
@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) {
if(changedByFormatText) {
changedByFormatText = false;
return;
} else {
changedByFormatText = true;
etMoney.setText(currencyFormat(etMoney.getText().toString()));
}
}
});