Domanda

I want to be able to calculate something depending on the input in 2 of 3 EditText. For Example: I make an input in ET 1 and 2 -> i get a calculation in ET 3. ET 1 and 3 -> calculation in ET 2... and so on.

I get it to work with 2 EditText but with 3 I get an 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;
        }
    }
}
È stato utile?

Soluzione

OK i just started to review my code again. Why hasn't anyone found an answer? It's really not that hard.

So i just just surrounded the if-statements in every try block with another if-statement which looks like this:

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

And now everything works just fine. There is no StackOverflowException anymore because the textwatcher only starts it's work where the edittext is focused. The text changes do not trigger an infinit loop anymore.

Altri suggerimenti

You should check if change in an EditText happened because of changes made in other EditText. Create a boolean field in the class and initialize it with false:

private boolean mIsChanging = false;

In afterTextChanged() check if this field is false or exit otherwise:

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

    mIsChanging = true;

    // Then do what you did previously...

    mIsChanging = false;
}

With Editable is possible, you need to use hashCodeFunction

@Override
public void afterTextChanged(Editable s) {
    if (editText.getText().hashCode() == s.hashCode()) {
        // some
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top