我有一个编辑文本视图,用于计算与货币相关的内容。 编辑文本从0.00开始 这是出于计费目的,其中供应商输入要向客户收取的账单金额。用户只能在编辑文本框中输入0-9的数字。
如果用户输入1,则变为0.01
如果用户输入2,则变为0.12,依此类推
这是我与TextWatcher一起使用的代码,它运行得很好。
etInitialOtherBill.addTextChangedListener(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.toString().equals(currentO) && !s.toString().equals("")){
etInitialOtherBill.removeTextChangedListener(this);
String cleanString = s.toString().replace(".", "");
double parsed = Double.parseDouble(cleanString);
String formatted = NumberFormat.getCurrencyInstance().format((parsed/100));
currentO = formatted.replace(NumberFormat.getCurrencyInstance().getCurrency().getSymbol(),"");
//new
currentO=currentO.replace("\u00A0","").replace(",","");
etInitialOtherBill.setText(currentO);
etInitialOtherBill.setSelection(currentO.length());
etInitialOtherBill.addTextChangedListener(this);
}
}
@Override
public void afterTextChanged(Editable s) {
Double initialMBill, initialOBill;
if (etInitialMedicineBill.getText().toString().equals("") || etInitialMedicineBill.getText().toString().equals(".")){
initialMBill=0.00;
}else {
initialMBill= Double.valueOf(etInitialMedicineBill.getText().toString());
}
if (etInitialOtherBill.getText().toString().equals("") || etInitialOtherBill.getText().toString().equals(".")){
initialOBill=0.00;
}else {
initialOBill= Double.valueOf(etInitialOtherBill.getText().toString());
}
Double discountM =Math.round( initialMBill * 100.0 *discountToConsumer ) / 100.0;
Double netMBill = Math.round( initialMBill * 100.0 *amountPayable ) / 100.0;
Double finalBill = netMBill+initialOBill;
tvDiscountMedicine.setText(df2.format(discountM));
tvNetMedicineBill.setText(df2.format(netMBill));
tvFinalBill.setText(df2.format(finalBill));
}
});
afterTextChanged
是执行一些计算并在TextView
目前我尝试的是
RxTextView.textChanges(editText)
.map(new Func1<CharSequence, CharSequence>() {
@Override
public CharSequence call(CharSequence charSequence) {
//perform calculations as in onTextChanged
//This causes the infinite loop. Adding if statements did not solve my problem either
return someValue
}
})
.subscribe(new Action1<CharSequence>() {
@Override
public void call(CharSequence charSequence) {
//If user inputs a number which was formatted, then display it
editText.setText(charSequence);
editText.setSelection(charSequence.length()
}
});
现在,这将代码置于无限循环中,removeTextChangedListener(this)
避免了这种情况。我曾尝试使用subscription.unsubscribe()
,但这并没有让我任何地方。
我正在寻找一些指导,我可以再次尝试这一点。
答案 0 :(得分:0)
您可以尝试创建自己的CustomEditText,并在下面的代码中实现想要的行为。我希望这有帮助
public class CustomEditText extends EditText{
List<TextWatcher> textWatchers = new ArrayList<>();
private TextWatcher watcher;
public CustomEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void addTextChangedListener(TextWatcher watcher) {
textWatchers.add(watcher);
}
@Override
public void setText(CharSequence text, BufferType type) {
if (watcher == null) {
watcher= new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
for (TextWatcher watcher : textWatchers) {
watcher.beforeTextChanged(s, start, count, after);
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
for (TextWatcher watcher : textWatchers) {
watcher.onTextChanged(s, start, before, count);
}
}
@Override
public void afterTextChanged(Editable s) {
for (TextWatcher watcher : textWatchers) {
watcher.afterTextChanged(s);
}
}
};
}
super.removeTextChangedListener(watcher);
super.setText(text, type);
super.addTextChangedListener(watcher);
}
}
MainActivity
final CustomEditText editText = (CustomEditText) findViewById(R.id.custom_edit_text);
RxTextView.textChanges(editText)
.map(new Func1<CharSequence, CharSequence>() {
@Override
public CharSequence call(CharSequence charSequence) {
return charSequence;
}
})
.subscribe(new Action1<CharSequence>() {
@Override
public void call(CharSequence charSequence) {
Log.d(TAG, "call: Check infinite loop");
editText.setText(charSequence + " " + charSequence.length());
editText.setSelection(charSequence.length());
}
});
答案 1 :(得分:0)
更短,但是hacky解决方案。
{
ConnectableObservable<TextViewTextChangeEvent> onTextChanges =
RxTextView.textChangeEvents(textView).publish();
onTextChanges
.filter(event -> isUser(event.view()))
.map(this::changeProps)
.subscribe(event -> {
textView.setTag(Source.APP);
setTextProps(textView, event);
});
onTextChanges.filter(event -> isApp(event.view()))
.delay(1, TimeUnit.MILLISECONDS).subscribe(event -> {
event.view().setTag(Source.USER);
});
onTextChanges.connect();
}
private boolean isApp(View view) {
return view.getTag() == null || Source.APP.equals(view.getTag());
}
private boolean isUser(View view) {
return Source.USER.equals(view.getTag());
}
private static final class Source {
public static final String APP = "APP";
public static final String USER = "USER";
}