Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TextWatcher.afterTextChanged has incorrect string after backspace

I am using a TextWatcher to listen to key inputs. When user types '@', I open up a listactivity and user has to choose from the list. Once choosen, I place the selected item's text(including the initial @) to the edittext and normal editing goes on.

The issue is that when I press backspace, the string I get in aftertextchanged event is wrong, and the listactivity again pops up.

editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count)
        {

        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after)
        {

        }

        @Override
        public void afterTextChanged(Editable s)
        {
            String str = s.toString();

            if (str.length() > 0)
            {
                if (str.substring(str.length() - 1).equals("@"))
                {
                    Intent i = new Intent(MessageComposeActivity.this, MembersListActivity.class);
                    startActivityForResult(i, Util.MEMBERS_LIST);
                }
            }
        }
    });

And in onActivityResult:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == Util.MEMBERS_LIST)
        if (resultCode == RESULT_OK)
        {
            editText.setText(editText.getText().toString() + data.getExtras().get("screenname") + " ");
            editText.setSelection(editText.getText().length());
        }
}

For example:

In EditText I type '@', and the activity pops up and I choose 'James'. The EditText now shows @James. If I press backspace once or twice, the listactivity again pops up while the EditText shows @Jam.

PS: The afterTextChanged() is called twice sometimes for a backspace (or any key), on 2nd execution of afterTextChanged() I get wrong input string. On first execution of afterTextChanged() I get @Jam, and on 2nd execution I get '@' hence listactivity pops up.

Question: Why afterTextChanged() is called twice, AND why on 2nd execution I get wrong text?

Thanks a lot.

like image 215
droidbee Avatar asked Nov 13 '22 11:11

droidbee


1 Answers

I had the exact same problem. I do not know what causes the extra false callback with a 0 length Editable/CharacterSequence.

I was looking for changes on an EditText that actually resulted in an empty EditText. I ended up having to implement a Handler to check the EditText length after 500 ms. You might have to make your edittext static or final. It should look something like this:

     final Handler handler =new Handler();
     final Runnable r = new Runnable(){

         @Override
         public void run()
         {
            //

             String str = editText.getText().toString();

             if (str.length() > 0)
             {
                 if (str.substring(str.length() - 1).equals("@"))
                 {
                     Intent i = new Intent(MessageComposeActivity.this, MembersListActivity.class);
                     startActivityForResult(i, Util.MEMBERS_LIST);
                 }
             }
         }
     } ;



    editText.addTextChangedListener(new TextWatcher()
    {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3)
        {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i2, int i3)
        {

        }

        @Override
        public void afterTextChanged(Editable s)
        {

            handler.postDelayed(r,500);

        }
    });
like image 149
joseph Avatar answered Nov 15 '22 07:11

joseph