set colour to multiple non sequential parts of a spannable text android

581 views Asked by At

I have a spannable text. It has a string for eg, TO, BE, IS, DO. I'm reading an arraylist from database [BE, DO]. I'm trying to change the colour of BE and DO. My java code:

Spannable spans;
private void clickableDictionary(String words) {

    final ForegroundColorSpan fcs = new ForegroundColorSpan(Color.rgb(33, 150, 243));

    ArrayList<String> myList = new ArrayList<>(Arrays.asList(words.split(", ")));
    String vocab = object.fetchDataVOCAB(getApplicationContext(), wordLength);
    ArrayList<String> myListVOCAB = new ArrayList<>(Arrays.asList(vocab.split(", ")));

    words_done.setMovementMethod(LinkMovementMethod.getInstance()); //words_done is the textView
    words_done.setText(words, TextView.BufferType.SPANNABLE);
    spans = (Spannable) words_done.getText();
    if (myListVOCAB.toString().replace("[", "").replace("]", "") != "") {
        System.out.println("-------VOCAB: "+myListVOCAB+" size of done words: "+myList.size());
        int indexStart;
        int indexEnd;

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

            indexStart = words.indexOf(myListVOCAB.get(i));
            System.out.println("-------VOCAB startIndex: "+indexStart+"for loop index:---"+i);
            indexEnd = indexStart + (myListVOCAB.get(i).length());
            System.out.println("-------VOCAB endIndex: " + indexEnd);

            spans.setSpan(fcs, indexStart, indexEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            System.out.println("-------color change startIndex: " + indexStart + "endIndex:---" + indexEnd);
        }
    }

        BreakIterator iterator = BreakIterator.getWordInstance(Locale.US);
        iterator.setText(words);
        int start = iterator.first();
        for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator
                .next()) {
            String possibleWord = words.substring(start, end);
            if (Character.isLetterOrDigit(possibleWord.charAt(0))) {
                ClickableSpan clickSpan = getClickableSpan(possibleWord, start, end);

                spans.setSpan(clickSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            }
        }

}

private ClickableSpan getClickableSpan(final String word, final int start, final int end) {
    return new ClickableSpan() {
        final String mWord;
        {
            mWord = word;
        }

        @Override
        public void onClick(View widget) {

            String s = object.fetchDataVOCAB(getApplicationContext(), wordLength);

            if (s.isEmpty()) {
                s = mWord;
                object.writeVOCAB(getApplicationContext(), wordLength, s, vocabCount + 1);
                vocab.setText("Vocab: " + object.readVOCAB(getApplicationContext(), wordLength));
            }

            else {
                if (!s.contains(mWord)) {
                    s = s + ", " + mWord;
                    object.writeVOCAB(getApplicationContext(), wordLength, s, object.readVOCAB(getApplicationContext(), wordLength) + 1);
                    vocab.setText("Vocab: " + object.readVOCAB(getApplicationContext(), wordLength));
                }
            }

            spans.setSpan(new ForegroundColorSpan(Color.rgb(33, 150, 243)), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            new atask().execute(mWord);
            widget.invalidate();
        }

        public void updateDrawState(TextPaint ds) {// override updateDrawState
            ds.setUnderlineText(false); // set to false to remove underline
        }

    };

}

myList contains the words i want to print as clickable. myListVOCAB contains the word I want to print in blue. I'm populating these from databases. Also I'm trying to make a word blue at the very moment when it is clicked as well. My problem is when the intent is started only one word is printed in blue, the last word of myListVOCAB. I think I'm not using the setSpan method accordingly. Please share some suggestions on how to set parts of spannable to change colour where the parts are not pre-set in string.

1

There are 1 answers

7
Rajan Bhavsar On

The way to Change the Color for String you got from List as follows :

TextView TV = (TextView)findViewById(R.id.mytextview01);

Spannable wordtoSpan = new SpannableString(list.get(0));  



wordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

TV.setText(wordtoSpan);

Now you need to manage the text from list only.