Highlight words in text form when pressed

I have a TextView to display a paragraph of text, and I want my application to pronounce individual words when clicked using TTS. It would be better if the words were highlighted when pressed. I implemented it using ClickableSpan for each word. It works almost perfectly, except that I don’t see how reset the highlighted state returns to normal after playback is complete. Each time I press a new word, the previous word loses its selection and the new word is highlighted, but I don’t know how to delete the selection as soon as the TTS calls back:

My TextView:

<TextView android:id="@+id/sentence" ... android:textColorHighlight="@color/i_blue" /> 

To populate a TextView, I use:

 SpannableStringBuilder strBuilder = new SpannableStringBuilder(); Iterator<Word> iterator = e.getWordList().iterator(); int wordStart, wordEnd; while (iterator.hasNext()) { Word w = iterator.next(); wordStart = strBuilder.length() + w.getPrefix().length(); wordEnd = wordStart + w.getWord().length(); strBuilder.append(w.getPrefix() + w.getWord() + w.getSuffix()); final String currentWord = w.getWord(); ClickableSpan readWord = new ClickableSpan() { private String clickedWord = currentWord; public void onClick(View view) { Message msg = m_HandlerReadWord.obtainMessage(); msg.obj = clickedWord; m_HandlerReadWord.sendMessage(msg); } @Override public void updateDrawState(TextPaint ds) { super.updateDrawState(ds); ds.setUnderlineText(false); } }; strBuilder.setSpan(readWord, wordStart, wordEnd, 0); } m_SentenceView.setText(strBuilder); m_SentenceView.setMovementMethod(LinkMovementMethod.getInstance()); 

And I also have this method, which is called once, when the TTS calls the callback, when it is done, playing the word:

 public void resetHighlight() { //What can I do there to reset any highlighted word? } 

Is there a way I can do this? Or is there a better approach than ClickableSpan?

+4
source share
1 answer

I finally found a trick that works for me. When the color of text in a TextView changes, all the highlights are reset. Therefore, if I cause a change in the color of the text in the TTS callback, then the selection is deleted. The dirty part is that the triggered color change must be a different color. Therefore, I have to change colors both during TTS access and in the onClick handler from ClickableSpan. And I set these two colors to two almost identical colors.

My ClickableSpan:

 final int AlmostBlack = m_Resources.getColor(R.color.i_black_almost); ClickableSpan readWord = new ClickableSpan() { private int almostBlack = AlmostBlack; public void onClick(View view) { TextView v = (TextView) view; v.setTextColor(almostBlack); ... 

And in the handler, when the TTS calls back:

 m_SentenceView.setTextColor(m_Resources.getColor(R.color.i_black)); 

If you want to do something like this, but without waiting for the TTS or something to call back, you can use the list of color states to trigger a color change when you click or release the view:

List of color states, res / color / clickable_words.xml:

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:color="@color/i_black_almost" android:state_pressed="true"/> <item android:color="@color/i_black" /> </selector> 

TextView:

 <TextView android:id="@+id/sentence" ... android:textColor="@color/clickable_words" android:textColorLink="@color/clickable_words" android:textColorHighlight="@color/i_blue" /> 
+2
source

All Articles