3

I have three Edittext.when i change first Edittext value,third Edittext value will change by Textwatcher.when i change third Edittext ,first edittext value will change by Textwatcher.App is crasing when i run the code.

Here is my code

   qty = (EditText) findViewById(R.id.qty);
   rate = (EditText) findViewById(R.id.rate);
   amount = (EditText) findViewById(R.id.amount);

   qty.addTextChangedListener(new TextWatcher() {
       @Override
       public void onTextChanged(CharSequence s, int start, int before, int count) { 
           // TODO Auto-generated method stub
       }

       @Override
       public void beforeTextChanged(CharSequence s, int start, int count, int after) {
           // TODO Auto-generated method stub
       }

       @Override
       public void afterTextChanged(Editable s) {
           // TODO Auto-generated method stub
           String qtyvalue = qty.getText().toString();
           String ratevalue = rate.getText().toString();

           if (qtyvalue.equals("") || ratevalue.equals("")) {
               val1 = 0d;
               val2 = 0d;
           } else {
               val1 = Double.parseDouble(qtyvalue);
               val2 = Double.parseDouble(ratevalue);
           }

           amount.setText(Double.toString(val1 * val2));
       }
   });

   amount.addTextChangedListener(new TextWatcher() {
       @Override
       public void onTextChanged(CharSequence s, int start, int before, int count) {
           // TODO Auto-generated method stub
       }

       @Override
       public void beforeTextChanged(CharSequence s, int start, int count, int after) {
           // TODO Auto-generated method stub
       }

       @Override
       public void afterTextChanged(Editable s) {
           // TODO Auto-generated method stub
           String amountvalue = amount.getText().toString();
           String ratevalue = rate.getText().toString();

           if (amountvalue.equals("") || ratevalue.equals("")) {
               val3 = 0d;
               val4 = 0d;
            } else {
               val3 = Double.parseDouble(amountvalue);
               val4 = Double.parseDouble(ratevalue);
            }

            System.out.println(Double.toString((double)val3/val4));    
            qty.setText(Double.toString((double)val3/val4));
        }
    });

Logcat

 java.lang.StackOverflowError
            at android.text.method.ReplacementTransformationMethod$ReplacementCharSequence.getChars(ReplacementTransformationMethod.java:151)
            at android.text.TextUtils.getChars(TextUtils.java:78)
            at android.text.TextUtils.indexOf(TextUtils.java:111)
            at android.text.StaticLayout.generate(StaticLayout.java:209)
            at android.text.DynamicLayout.reflow(DynamicLayout.java:324)
            at android.text.DynamicLayout.<init>(DynamicLayout.java:174)
            at android.widget.TextView.makeSingleLayout(TextView.java:6964)
            at android.widget.TextView.makeNewLayout(TextView.java:6813)
            at android.widget.TextView.checkForRelayout(TextView.java:7409)
            at android.widget.TextView.setText(TextView.java:4300)
            at android.widget.TextView.setText(TextView.java:4137)
            at android.widget.EditText.setText(EditText.java:104)
            at android.widget.TextView.setText(TextView.java:4112)
            at com.example.admin.foms.Delivery$1.afterTextChanged(Delivery.java:93)
            at android.widget.TextView.sendAfterTextChanged(TextView.java:8293)
            at android.widget.TextView.setText(TextView.java:4307)
            at android.widget.TextView.setText(TextView.java:4137)
            at android.widget.EditText.setText(EditText.java:104)
            at android.widget.TextView.setText(TextView.java:4112)
            at com.example.admin.foms.Delivery$2.afterTextChanged(Delivery.java:127)
            at android.widget.TextView.sendAfterTextChanged(TextView.java:8293)
            at android.widget.TextView.setText(TextView.java:4307)
            at android.widget.TextView.setText(TextView.java:4137)
            at android.widget.EditText.setText(EditText.java:104)
            at android.widget.TextView.setText(TextView.java:4112)
            at com.example.admin.foms.Delivery$1.afterTextChanged(Delivery.java:93)
            at android.widget.TextView.sendAfterTextChanged(TextView.java:8293)
            at android.widget.TextView.setText(TextView.java:4307)
            at android.widget.TextView.setText(TextView.java:4137)
            at android.widget.EditText.setText(EditText.java:104)
            at android.widget.TextView.setText(TextView.java:4112)
            at com.example.admin.foms.Delivery$2.afterTextChanged(Delivery.java:127)
            at android.widget.TextView.sendAfterTextChanged(TextView.java:8293)
            at android.widget.TextView.setText(TextView.java:4307)
            at android.widget.TextView.setText(TextView.java:4137)
            at android.widget.EditText.setText(EditText.java:104)
            at android.widget.TextView.setText(TextView.java:4112)
            at com.example.admin.foms.Delivery$1.afterTextChanged(Delivery.java:93)
            at android.widget.TextView.sendAfterTextChanged(TextView.java:8293)
            at android.widget.TextView.setText(TextView.java:4307)
            at android.widget.TextView.setText(TextView.java:4137)
            at android.widget.EditText.setText(EditText.java:104)
            at android.widget.TextView.setText(TextView.java:4112)
            at com.example.admin.foms.Delivery$2.afterTextChanged(Delivery.java:127)
            at android.widget.TextView.sendAfterTextChanged(TextView.java:8293)
            at android.widget.TextView.setText(TextView.java:4307)
            at android.widget.TextView.setText(TextView.java:4137)
            at android.widget.EditText.setText(EditText.java:104)
            at android.widget.TextView.setText(TextView.java:4112)
            at com.example.admin.foms.Delivery$1.afterTextChanged(Delivery.java:93)
            at android.widget.TextView.sendAfterTextChanged(TextView.java:8293)
            at android.widget.TextView.setText(TextView.java:4307)
            at android.widget.TextView.setText(TextView.java:4137)
            at android.widget.EditText.setText(EditText.java:104)
            at android.widget.TextView.setText(TextView.java:4112)
            at com.example.admin.foms.Delivery$2.afterTextChanged(Delivery.java:127)
            at android.widget.TextView.sendAfterTextChanged(TextView.java:8293)
            at android.widget.TextView.setText(TextView.java:4307)
            at android.widget.TextView.setText(TextView.java:4137)
            at android.widget.EditText.setText(EditText.java:104)
            at android.widget.TextView.setText(TextView.java:4112)
            at com.example.admin.foms.Delivery$1.afterTextChanged(Delivery.java:93)
            at android.widget.TextView.sendAfterTextChanged(TextView.java:8293)
            at android.widget.TextView.setText(TextView.java:4307)
            at android.widget.TextView.setText(TextView
ItsVibi
  • 63
  • 1
  • 9

5 Answers5

2

According to this answer, to avoid recursive when changing text, you can set flag to afterTextChanged method, just like this:

 boolean preventUpdate = false;

   @Override
   public void afterTextChanged(Editable s) {
      if(preventUpdate){
         preventUpdate = false; // reset flag after calling
         return;
      }

     // your logic 

        // prevent update after change value
        preventUpdate = true;   
        qty.setText(Double.toString((double)val3/val4));
   }

If two EdiText change text of each other, you should add another flag to make sure they don't notify text change again (thinking about your logic, whenever you would like to use afterTextChanged method ).

Community
  • 1
  • 1
ductran
  • 10,043
  • 19
  • 82
  • 165
1

can you do something like :

        // temporary disable the listener
        edt.removeTextChangedListener(this);
        // change the text
        edt.setText("Some text");
        // enable it again
        edt.addTextChangedListener(this);
rahul
  • 1,095
  • 8
  • 22
0

You have set TextWatcher on both EditText(qty and amount) and You are setting Text on alternate EditText on TextChange.

Upon changing Text in amount EditText it will change value in qty EditText(becuase of TextWatcher), now qty EditText value is Change so it will again try to change value of amount EditText(becuase of TextWatcher) and process go on.. And there comes Stackoverflow error.

Dhaval Patel
  • 10,119
  • 5
  • 43
  • 46
0

Reason for the stackoverflow is the infinite loop that has been induced because of TextWatcher() i.e EditTextA changes w.r.t. EditTextB and vice-versa. Thus creating an endless loop with stack getting exhausted with the local variables of the functions.

SOLUTIONS:

Community
  • 1
  • 1
thepace
  • 2,221
  • 1
  • 13
  • 21
-1

In the last line of your text watcher, compare the current text to the one that you want to set. If they are equal, don't set the text. That will avoid the endless loop.

Bananeweizen
  • 21,797
  • 8
  • 68
  • 88
  • I'd really like to know why this was downvoted. That solution is implemented in one of my projects and surely works well. – Bananeweizen Dec 14 '16 at 07:11