Android: RxTextView.textChanges для EditText проходит бесконечный цикл - PullRequest
0 голосов
/ 10 октября 2018

Что мне нужно: Я хочу наблюдать за изменениями в EditText и форматировать в каком-то числе DecimalFormat.

Что я пытаюсь: IЯ пытаюсь наблюдать EditText с Rx .

В чем проблема: После того, как я начинаю печатать, он переходит в цикл INFINITE .Ниже приведен код, который я пытаюсь сделать.

ProductDetailsActivity.java :

public class ProductDetailsActivity extends AppCompatActivity {    
    @BindView(R.id.et_product_price)
    EditText et_product_price;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_product_details);

        ButterKnife.bind(this);

        RxTextView.textChanges(et_product_price)
            .skipInitialValue()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(str -> {

                double amount = Double.parseDouble(str.toString());
                DecimalFormat formatter = new DecimalFormat("#,##,###");
                String formatted = formatter.format(amount);
                et_product_price.setText(formatted);

                Log.e("mk", "output: " + formatted);

            }, throwable -> {
                Log.e("mk", "Error: " + throwable.getMessage());
            });
    }
}

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Наконец я вернулся к TextWatcher, чтобы найти решение.Я написал onCreate методом, как показано ниже.

et_product_price.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) {

        }

        @Override
        public void afterTextChanged(Editable s) {

            if (!TextUtils.isEmpty(s)) {

                String enteredProductPrice = s.toString().replace(",", "");

                double enteredProductPriceDouble = Double.parseDouble(enteredProductPrice);
                String formattedProductPrice = new DecimalFormat("#,##,###").format(enteredProductPriceDouble);

                et_product_price.removeTextChangedListener(this);

                et_product_price.setText(formattedProductPrice);
                et_product_price.setSelection(et_product_price.getText().length());

                et_product_price.addTextChangedListener(this);
            }
        }
    });

Это может кому-нибудь помочь.

0 голосов
/ 10 октября 2018

Каждый раз, когда вы звоните setText(), даже если фактический текст не отличается, это будет считаться событием «текст изменен».Это означает, что эта строка является виновником:

et_product_price.setText(formatted);

Когда вы звоните в первый раз, это вызовет событие изменения текста, так что ваш подписчик будет вызван снова.Он проанализирует и отформатирует дубль, а затем снова вызовет setText().И так далее.

Есть много способов решить эту проблему, но в основном вам просто нужно убедиться, что вы не вызываете setText(), если «новое» значение равно «старому» значению.

if (!formatted.equals(et_product_price.getText().toString()) {
    et_product_price.setText(formatted);
}
...