TextWatcher для нескольких EditText

Я хочу иметь возможность что-то вычислить в зависимости от ввода в 2 из 3 EditText. Например: я делаю ввод в ET 1 и 2 -> я получаю расчет в ET 3. ET 1 и 3 -> расчет в ET 2... и так далее.

Я заставляю его работать с 2 EditText, но с 3 я получаю StackOverFlowError.

private class GenericTextWatcher implements TextWatcher {

    private View view;

    private GenericTextWatcher(View view) {
        this.view = view;
    }

    public void beforeTextChanged(CharSequence charSequence, int i, int i1,
            int i2) {
    }

    public void onTextChanged(CharSequence charSequence, int i, int i1,
            int i2) {
    }

    public void afterTextChanged(Editable editable) {
        switch (view.getId()) {
        case R.id.liter_input:
            try {
                if (amount_widget.getText().toString().equals(" ") == false
                        || literPrice_widget.getText().toString()
                                .equals(" ") == false
                        || price_widget.getText().toString().equals(" ") == false) {
                    double editTextCalc = Double.parseDouble(amount_widget
                            .getText().toString())
                            * Double.parseDouble(literPrice_widget
                                    .getText().toString());
                    editTextCalc = Math.round(editTextCalc * 100) / 100.0;
                    price_widget.setText(String.valueOf(decimalFormat
                            .format(editTextCalc)));
                }

            } catch (Exception e) {
                // TODO: handle exception
            }
            break;
        case R.id.literprice_input:
            try {
                if (amount_widget.getText().toString().equals(" ") == false
                        || literPrice_widget.getText().toString()
                                .equals(" ") == false
                        || price_widget.getText().toString().equals(" ") == false) {
                    double editTextCalc = Double.parseDouble(amount_widget
                            .getText().toString())
                            * Double.parseDouble(literPrice_widget
                                    .getText().toString());
                    editTextCalc = Math.round(editTextCalc * 100) / 100.0;
                    price_widget.setText(String.valueOf(decimalFormat
                            .format(editTextCalc)));
                }

            } catch (Exception e) {
                // TODO: handle exception
            }
            break;
        case R.id.price_input:
            try {
                if (amount_widget.getText().toString().equals(" ") == false
                        || literPrice_widget.getText().toString()
                                .equals(" ") == false
                        || price_widget.getText().toString().equals(" ") == false) {
                    double editTextCalc = Double.parseDouble(amount_widget
                            .getText().toString())
                            / Double.parseDouble(price_widget.getText()
                                    .toString());
                    editTextCalc = Math.round(editTextCalc * 100) / 100.0;
                    literPrice_widget.setText(String.valueOf(decimalFormat
                            .format(editTextCalc)));
                }

            } catch (Exception e) {
                // TODO: handle exception
            }
            break;
        }
    }
}

person mike.b93    schedule 19.04.2013    source источник


Ответы (3)


Хорошо, я только что снова начал просматривать свой код. Почему никто не нашел ответа? Это действительно не так сложно.

Поэтому я просто окружил if-statements в каждом блоке try другим if-statement, который выглядит так:

if(edittext.isFocused()){
   try-catch block
}

И теперь все работает просто отлично. StackOverflowException больше нет, потому что textwatcher начинает свою работу только там, где сосредоточен edittext. Изменения текста больше не вызывают бесконечный цикл.

person mike.b93    schedule 04.05.2013
comment
Блог был удален - person ; 22.03.2014

Вы должны проверить, произошло ли изменение в EditText из-за изменений, сделанных в другом EditText. Создайте в классе поле boolean и инициализируйте его значением false:

private boolean mIsChanging = false;

В afterTextChanged() проверьте, является ли это поле false или выйдите в противном случае:

public void afterTextChanged(Editable editable) {
    if (mIsChanging) {
        return;
    }

    mIsChanging = true;

    // Then do what you did previously...

    mIsChanging = false;
}
person Michael    schedule 19.04.2013
comment
Хорошо, StackOverFlowError исчез, но я получаю очень странное поведение. при вводе чего-то в моем 2-м EditText появляется что-то очень отличное от того, что я ввел, и при удалении моего ввода эти числа становятся больше и прыгают.. Трудно объяснить.. - person mike.b93; 19.04.2013
comment
В этом случае сложно что-то порекомендовать. Вы можете попробовать отладить его. Я уверен, что вы сможете довольно легко выяснить, в чем проблема. - person Michael; 19.04.2013

С Editable возможно, вам нужно использовать hashCodeFunction

@Override
public void afterTextChanged(Editable s) {
    if (editText.getText().hashCode() == s.hashCode()) {
        // some
    }
}
person steving21    schedule 17.09.2015