• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps updateDrawState on spannable question

Cruclax

Lurker
Jul 16, 2014
2
0
Hi All,

I have a pretty specific question that no one has been able to answer so far.

I have a function that parses a text with specific markup and adds clickableSpans -(extended as TouchableSpan in my case- to a SpannableStringBuilder (ssb) to make text highlightable and check some data

[HIGH]textView.setMovementMethod(new LinkTouchMovementMethod());
ssb = addClickablePart(chapterTextStr,markupCharactersArray, false);

textView.setText(ssb);
// PARSE MARKERS AND CREATE CLICKABLE SPANS FUNCTION
private static SpannableStringBuilder addClickablePart(
String chapterTextStr2, final String[] mcArray,
final boolean parseVocab) {
SpannableStringBuilder ssb2 = new SpannableStringBuilder(chapterTextStr2);

String[] markupOpen = { "|*", "|_", "|=", "|@" };
String [] markupClose = { "*|", "_|", "=|", "@|"};
String [] spantype = { "idea", "topic", "detail", "dummy"};
for( int i=0; i<markupOpen.length; i++){
index = chapterTextStr2.indexOf(markupOpen);
index2 = 0;
while (index != -1) {

index2 = chapterTextStr2.indexOf(markupClose, index);
TouchableSpan touchableSpan = new TouchableSpan() {

@Override
public void onClick(View widget) {
this.setPressed(true);

if (selectedHighlighter == "detail") {
this.setSpanColor(detailColor);
this.setSpanTypeSelected("detailSelected");
} else if (selectedHighlighter == "idea") {
this.setSpanColor(ideaColor);
this.setSpanTypeSelected("ideaSelected");
} else if (selectedHighlighter == "topic") {
this.setSpanColor(topicColor);
this.setSpanTypeSelected("topicSelected");
} else {
this.setSpanColor(Color.TRANSPARENT);
this.setSpanTypeSelected("");
}
}

private boolean mIsPressed;

public void setPressed(boolean isSelected) {
mIsPressed = isSelected;
}

// THIS UPDATES THE DRAW STATE TO CHANGE THE SPAN BACKGROUND COLOR DEPENDING ON THE "SELECTED HIGHLIGHTER"
@Override
public void updateDrawState(TextPaint ds) {
int spanColor = this.getSpanColor();
super.updateDrawState(ds);
ds.setColor(Color.BLACK);
ds.bgColor = mIsPressed ? spanColor : 0xffeeeeee;
ds.setUnderlineText(false);
}

};
touchableSpan.setSpanType(spantype);
ssb2.setSpan(touchableSpan, index + 2, index2, 0);

try {
chapterTextStr2 = chapterTextStr2.substring(0,index)
+chapterTextStr2.substring(index+2,index2)
+chapterTextStr2.substring(index2+2,chapterTextStr2.length());
ssb2.delete(index, index+2);
ssb2.delete(index2-2, index2);
} catch(RuntimeException e) {

}

index = chapterTextStr2.indexOf(markupOpen,index2-4);

}
}

chapterTextStr = chapterTextStr2;

return ssb2;
}[/HIGH]

It works pretty good. But the problem is that when I have very long texts with lots of clickableSpans, it takes a lot of time to react, since it is executing update draw state for every element.

Anyone can think of a way to avoid this and only update the draw state on the clicked element?
 

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones