I want to draw a SpannedString
to a Canvas
.
SpannableString spannableString = new SpannableString("Hello World!");
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.YELLOW);
spannableString.setSpan(foregroundSpan, 1, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(backgroundSpan, 3, spannableString.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
The above example was drawn using a TextView
, which in turn uses a Layout
to draw text with spans. I know that using a Layout
is the recommended way to draw text to the canvas. However, I am making my own text layout from scratch, so I need to implement this myself.
Doing something like this doesn't work
canvas.drawText(spannableString, 0, spannableString.length(), 0, 0, mTextPaint);
because drawText
only gets the text from the spannableString
, not any of the spans. The drawing colors are handled separately by TextPaint
.
How do I use canvas.drawText
(or drawTextRun
) to draw the span information (specifically foreground and background color here)?
Related
- How to loop through the spans in a SpannedString or SpannableString in Android
- Is it possible to display multi-color text with one call to Canvas.drawText()?
Plan for a solution
I was going to directly do a self answer but this is turning out to be more difficult than I thought. So I will post first and then add an answer whenever I can figure it out. (I would of course welcome anyone to answer first.)
Here are the pieces that I have so far:
- Draw each span range as a separate text run
- Use
drawTextRun
to draw the text (examples) (update: not added until API 23) - Use
getRunAdvance
to measure where to start the next text run (update: not added until API 23, usemeasureText
instead) - The background color will probably need to be drawn separately (with
drawRect
or maybedrawPath
? See here, here, and here.) - Source code for
TextView
,StaticLayout
, andTextLine