Search code examples
javaandroidandroid-edittextspannablestring

How to highlight Multiple words in EditText?


Currently I'm developing Spelling & Grammar checking app. It has EditText where user can input text & one button called "Check Text " upon click on button app will call LanguageTool API to check text & returns JSON response with result .

Here is screenshot of app :enter image description here

Here is code which I have tried so far for highlighting multiple words but this code only highlights last word from array which I have created:

for (int i = 0; i < errorStrings.size(); i++) {

// Here textToCheck is EditText & errorStrings is ArrayList of type WrongString class which i have created to hold Error string , offset & length.

Spannable wordtoSpan = new SpannableString(texttoSend);
wordtoSpan.setSpan(new BackgroundColorSpan(Color.BLUE),errorStrings.get(i).getOffset(),
                                        (errorStrings.get(i).getOffset()+errorStrings.get(i).getLength()), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                            textToCheck.setText(wordtoSpan);
}

Solution

  • I have wrote a simple method that allow you pass TextView (or child classes Button, Edittext etc.).

    1. If you want to highlight a text like in find word in paragraph. You can use below method like.

    setHighLightedText(yourTextView_Edittext_Button, "a");
    

    Which gives you result like this.

    enter image description here

        /**
         * use this method to highlight a text in TextView
         * @param tv TextView or Edittext or Button or child of TextView class
         * @param textToHighlight Text to highlight
         */
        public void setHighLightedText(TextView tv, String textToHighlight) {
            String tvt = tv.getText().toString();
            int ofe = tvt.indexOf(textToHighlight, 0);
            Spannable wordToSpan = new SpannableString(tv.getText());
            for (int ofs = 0; ofs < tvt.length() && ofe != -1; ofs = ofe + 1) {
                ofe = tvt.indexOf(textToHighlight, ofs);
                if (ofe == -1)
                    break;
                else {
                    wordToSpan.setSpan(new BackgroundColorSpan(0xFFFFFF00), ofe, ofe + textToHighlight.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    tv.setText(wordToSpan, TextView.BufferType.SPANNABLE);
                }
            }
        }
    

    2. If you want make clickable highlighted text (like click on terms & condition text) then use this code as below:

     setClickableHighLightedText(yourTextView_Edittext_Button, "go to settings", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO: do your stuff here 
            }
        });
    

    Which gives you result like

    enter image description here

    /**
     * use this method to set clickable highlighted a text in TextView
     *
     * @param tv              TextView or Edittext or Button or child of TextView class
     * @param textToHighlight Text to highlight
     */
    public void setClickableHighLightedText(TextView tv, String textToHighlight, View.OnClickListener onClickListener) {
        String tvt = tv.getText().toString();
        int ofe = tvt.indexOf(textToHighlight, 0);
        ClickableSpan clickableSpan = new ClickableSpan() {
            @Override
            public void onClick(View textView) {
                if (onClickListener != null) onClickListener.onClick(textView);
            }
    
            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(0xff0000ff);
                ds.setUnderlineText(true);
            }
        };
        SpannableString wordToSpan = new SpannableString(tv.getText());
        for (int ofs = 0; ofs < tvt.length() && ofe != -1; ofs = ofe + 1) {
            ofe = tvt.indexOf(textToHighlight, ofs);
            if (ofe == -1)
                break;
            else {
                wordToSpan.setSpan(clickableSpan, ofe, ofe + textToHighlight.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                tv.setText(wordToSpan, TextView.BufferType.SPANNABLE);
                tv.setMovementMethod(LinkMovementMethod.getInstance());
            }
        }
    }
    

    This is a workaround, you can customise spans according to your need. Some good tutorials Android text styles and one other