Detect changes in EditText (TextWatcher ineffective)

£可爱£侵袭症+ 提交于 2019-12-01 03:01:13

问题


I need to detect text changes in an EditText. I've tried TextWatcher, but it doesn't work in a way I would expect it to. Take the onTextChanged method:

public void onTextChanged( CharSequence s, int start, int before, int count )

Say I have the text "John" in already in the EditText. If press another key, "e", s will be "Johne", start will be 0, before will be 4, and count will be 5. The way I would expect this method to work would be the difference between what the EditText previously was, and what it's about to become.

So I would expect:

s = "Johne"
start = 4 // inserting character at index = 4
before = 0 // adding a character, so there was nothing there before
count = 1 // inserting one character

I need to be able to detect individual changes every time a key is pressed. So if I have text "John", I need to know "e" was added at index 4. If I backspace "e", I need to know "e" was removed from index 4. If I put the cursor after "J" and backspace, I need to know "J" was removed from index 0. If I put a "G" where "J" was, I want to know "G" replaced "J" at index 0.

How can I achieve this? I can't think of a reliable way to do this.


回答1:


Use a textwatcher and do the diff yourself. store the previous text inside the watcher, and then compare the previous text to whatever sequence you get onTextChanged. Since onTextChanged is fired after every character, you know your previous text and the given text will differ by at most one letter, which should make it simple to figure out what letter was added or removed where. ie:

new TextWatcher(){ 
    String previousText = theEditText.getText();

    @Override 
    onTextChanged(CharSequence s, int start, int before, int count){
        compare(s, previousText); //compare and do whatever you need to do
        previousText = s;
    }

    ...
}



回答2:


The best approach you can follow to identify text changes.

var previousText = ""


override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
    previousText = s.toString()
}

override fun onTextChanged(newText: CharSequence?, start: Int, before: Int, count: Int) {

    val position = start + before ;

    if(newText!!.length > previousText.length){ //Character Added
        Log.i("Added Character", " ${newText[position]} ")
        Log.i("At Position", " $position ")
    } else {  //Character Removed
        Log.i("Removed Character", " ${previousText[position-1]} ")
        Log.i("From Position", " ${position-1} ")
    }
}

override fun afterTextChanged(finalText: Editable?) { }



回答3:


You need to store and update the previous CharSequence every time the text is changed. You can do so by implementing the TextWatcher.

Example:

final CharSequence[] previousText = {""};
editText.addTextChangedListener(new TextWatcher()
{
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)
    {
    }

    @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
    {
        if(i1 > 0)
        {
            System.out.println("Removed Chars Positions & Text:");
            for(int index = 0; index < i1; index++)
            {
                System.out.print((i + index) + " : " + previousText[0].charAt(i + index)+", ");
            }
        }
        if(i2 > 0)
        {
            System.out.println("Inserted Chars Positions & Text:");
            for(int index = 0; index < i2; index++)
            {
                System.out.print((index + i) + " : " + charSequence.charAt(i + index)+", ");
            }
            System.out.print("\n");
        }
        previousText[0] = charSequence.toString();//update reference
    }

    @Override public void afterTextChanged(Editable editable)
    {
    }
});


来源:https://stackoverflow.com/questions/9459489/detect-changes-in-edittext-textwatcher-ineffective

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!