Question

I am working with android 2.2.

How to know which character is get deleted on backspace when editing text in custom auto complete in android.

public boolean onKeyUp(int keyCode,KeyEvent msg){  
     if(keyCode == KeyEvent.KEYCODE_DEL)
     {
        // how to find here which character is get deleted
     }
     return false;
}
Was it helpful?

Solution

String prevText = "";
public boolean onKeyUp(int keyCode,KeyEvent msg){  

     if(keyCode == KeyEvent.KEYCODE_DEL)
     {
        int pos = myEditText.getSelectionStart();
        char c = prevText.charAt(pos);
        // c is deleted
     }
     prevText = myEditText.getText.toString();
     return false;
}

OTHER TIPS

You can use add a TextWatcher to AutoCompleteTextView with addTextChangeListener(TextWatcher).

You don't need to listen to onKeyUp() the various TextWatcher methods inform you if the user is adding or removing text.

The easiest way is just keep last character that you type

int lastKeyCode;
public boolean onKeyUp(int keyCode,KeyEvent msg){  
     if(keyCode == KeyEvent.KEYCODE_DEL)
     {
        // print lastKeyCode here
        // how to find here which character is get deleted
     }
     lastKeyCode = keyCode;
     return false;
}

Try this, working for me

editText.addTextChangedListener(new TextWatcher() {
        String initialChar = null;
        int initCursorPosition = 0;

        @Override
        public void onTextChanged(CharSequence charSequence, int start, int before, int after) {
                char addedChar = 0;

                int finalCursorPosition = editText.getSelectionStart();
                if (finalCursorPosition - initCursorPosition > 0) {
                    addedChar = charSequence.charAt(finalCursorPosition - 1);
                    Log.d(TAG, "onTextChanged added: " + addedChar);
                   //added char

                } else {
                    char delChar = initialChar.charAt(initCursorPosition - 1);
                   Log.d(TAG, "onTextChanged deletedChar: " + delChar);
                   //deleted char
                }

        }

        @Override
        public void beforeTextChanged(CharSequence charSequence, int start, int before, int after) {
            Log.d(TAG, "textChange beforeTextChanged: " + charSequence);
            Log.d(TAG, "textChange cursorPosition: " + editText.getSelectionStart());
            initialChar = String.valueOf(charSequence);
            initCursorPosition = editText.getSelectionStart();
        }

        @Override
        public void afterTextChanged(Editable arg0) {
        }
    });
(Edittext).setOnKeyListener(new OnKeyListener()
{
    public boolean onKey(View v, int keyCode, KeyEvent event)
        {
            if(event.getKeyCode()==67)
            {
                if((EditText).getText().toString().length()>0)
                {
                               int pos = (Edittext).getSelectionStart();
                               Char c = (EditText).getText().toString.charAt(pos);
       Toast.makeText(getApplicationontext(),String.valueOf(c),Toast.LENGTH_SHORT).show();
                }
        }   
            return false;
        }
    });

I think it helps you

I know this is a very late answer, but this would be effective for future users.

First the KeyEvent.KEYCODE_DEL doesn't work for soft keyboard in latest android versions, so you have to create a custom EditText to handle that.

So we'll create a class to handle all null type in LatinIME

import android.text.SpannableStringBuilder;

public class EditableAccomodatingLatinIMETypeNullIssues extends SpannableStringBuilder {
    EditableAccomodatingLatinIMETypeNullIssues(CharSequence source) {
        super(source);
    }

    public static CharSequence ONE_UNPROCESSED_CHARACTER = "/";

    @Override
    public SpannableStringBuilder replace(final int
                                                  spannableStringStart, final int spannableStringEnd, CharSequence replacementSequence,
                                          int replacementStart, int replacementEnd) {
        if (replacementEnd > replacementStart) {
            super.replace(0, length(), "", 0, 0);

            return super.replace(0, 0, replacementSequence, replacementStart, replacementEnd);
        }
        else if (spannableStringEnd > spannableStringStart) {
            super.replace(0, length(), "", 0, 0);

            return super.replace(0, 0, ONE_UNPROCESSED_CHARACTER, 0, 1);
        }

        return super.replace(spannableStringStart, spannableStringEnd,
                replacementSequence, replacementStart, replacementEnd);
    }
}

Then we'll go ahead to create another class to handle the InputConnection of the custom EditText to be created

import android.os.Build;
import android.text.Editable;
import android.text.Selection;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.BaseInputConnection;

public class InputConnectionAccomodatingLatinIMETypeNullIssues extends BaseInputConnection {

    Editable myEditable = null;

    public InputConnectionAccomodatingLatinIMETypeNullIssues(View targetView, boolean fullEditor) {
        super(targetView, fullEditor);
    }
    @Override
    public Editable getEditable() {
        if(Build.VERSION.SDK_INT >= 14) {
            if(myEditable == null) {
                myEditable = new EditableAccomodatingLatinIMETypeNullIssues(
                        EditableAccomodatingLatinIMETypeNullIssues.ONE_UNPROCESSED_CHARACTER);
                Selection.setSelection(myEditable, 1);
            }
            else {
                int myEditableLength = myEditable.length();
                if(myEditableLength == 0) {
                    myEditable.append(
                            EditableAccomodatingLatinIMETypeNullIssues.ONE_UNPROCESSED_CHARACTER);
                    Selection.setSelection(myEditable, 1);
                }
            }
            return myEditable;
        }
        else {
            return super.getEditable();
        }
    }

    @Override
    public boolean deleteSurroundingText(int beforeLength, int afterLength) {
        if((Build.VERSION.SDK_INT >= 14) // && (Build.VERSION.SDK_INT < 19)
                && (beforeLength == 1 && afterLength == 0)) {
            return super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
                    && super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
        }
        else {
            return super.deleteSurroundingText(beforeLength, afterLength);
        }
    }
}

Then creating the custom EditText

import android.content.Context;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.jetbrains.annotations.NotNull;

public class CustomEditText extends androidx.appcompat.widget.AppCompatEditText {

    public CustomEditText(@NonNull @NotNull Context context) {
        super(context);
    }

    public CustomEditText(@NonNull @NotNull Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomEditText(@NonNull @NotNull Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        InputConnectionAccomodatingLatinIMETypeNullIssues baseInputConnection =
                new InputConnectionAccomodatingLatinIMETypeNullIssues(this, false);

        outAttrs.actionLabel = null;

        outAttrs.inputType = InputType.TYPE_NULL;

        outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE;

        return baseInputConnection;
    }

}

So in your .xml file, you can say something like

<your.package.name.CustomEditText
    <!set all required attributes-->
    />

Now in your java code, you have to listen for the Backspace click event and get the character to be deleted before it's deleted.

editText.setOnKeyListener(new View.OnKeyListener(){
    public boolean onKey(View v, int keyCode, KeyEvent event){
        if(event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_DEL) {
            int selStart = editText.getSelectionStart();
            int selEnd = editText.getSelectionEnd();
            //incase if some text in the textbox are selected, selStart and selEnd will
            //return the positions of both selected ends and you can get the text(s) deleted.
            
            //check if the selEnd is at 0, and if true, then there's not point going further
            if(selEnd == 0)
                return false;
            
            //if there is no texts selected, then reduce selStart by one to get the text to be deleted
            if(selStart == selEnd)
                selStart -= 1;
            
            String text = editText.getText().toString();
            //now this will get you char or chars to be deleted
            String charDeleted = text.substring(selStart, selEnd);
            
            //So before returning false to deleted the char,
            //let me answer the question asked also on the
            //comment section in Bobs' answer
            //which is to find the color code of the deleted char
            //Note, this is for only a single char, if you want to
            //handle for multiple chars, then you'll have to split the
            //deleted chars into an array and get the color codes for each
            
            //This will get all HTML text within the deleted char including the color code
            String htmlText = Html.toHtml((Spanned) editText.getText().subSequence(selStart, selEnd));
            
            //Now you have to use a HTML parser, and I'm using JSoup
            //Don't forget to implement the JSoup library into your project
            Document doc = Jsoup.parse(htmlText, "UTF-8");
            
            //Here I'm selecting a SPAN html tag, hoping that the char should be in a SPAN
            //If it's in a FONT or any other tag, then you select the tag instead and also
            //the attribute containing the color code
            Elements element = doc.select("span");
            //Attribute containing the color code for SPAN is the STYLE
            String style = element.attr("style");
            //So the style string would be giving you something like "color:#AABBCC;"
            //Where #AABBCC is the color code of the deleted char
        }
        return false;
    }
});

Try this

edittext.addTextChangeListener(new TextWatcher{
@override
  public void afterTextChanged(Editable s){
     String changedtext = s.toString();
}

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

@override
public void onTextChanged(CharSequence s, int start, int before, int count){}
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top