How to draw a Spanned String with Canvas.drawText in Android -
i want draw spannedstring
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 drawn using textview
, in turn uses layout
draw text spans. know using layout
recommended way draw text canvas. however, making own text layout scratch, need implement myself.
doing doesn't work
canvas.drawtext(spannablestring, 0, spannablestring.length(), 0, 0, mtextpaint);
because drawtext
gets text spannablestring
, not of spans. drawing colors handled separately textpaint
.
how use canvas.drawtext
(or drawtextrun
) draw span information (specifically foreground , background color here)?
related
- how loop through spans in spannedstring or spannablestring in android
- is possible display multi-color text 1 call canvas.drawtext()?
plan solution
i going directly self answer turning out more difficult thought. post first , add answer whenever can figure out. (i of course welcome answer first.)
here pieces have far:
- draw each span range separate text run
- use
drawtextrun
draw text (examples) (update: not added until api 23) - use
getrunadvance
measure start next text run (update: not added until api 23, usemeasuretext
instead) - the background color need drawn separately (with
drawrect
or maybedrawpath
? see here, here, , here.) - source code
textview
,staticlayout
, ,textline
for people coming question, should use staticlayout
draw spanned text. see this answer that.
however, if need draw spanned text yourself, need loop through spanned ranges , draw each 1 separately. need measure length of text in each span know start drawing next span.
the code below handles backgroundcolorspan
, foregroundcolorspan
.
// set spanned string 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); // draw each span 1 @ time int next; float xstart = 0; float xend; (int = 0; < spannablestring.length(); = next) { // find next span transition next = spannablestring.nextspantransition(i, spannablestring.length(), characterstyle.class); // measure length of span xend = xstart + mtextpaint.measuretext(spannablestring, i, next); // draw highlight (background color) first backgroundcolorspan[] bgspans = spannablestring.getspans(i, next, backgroundcolorspan.class); if (bgspans.length > 0) { mhighlightpaint.setcolor(bgspans[0].getbackgroundcolor()); canvas.drawrect(xstart, mtextpaint.getfontmetrics().top, xend, mtextpaint.getfontmetrics().bottom, mhighlightpaint); } // draw text optional foreground color foregroundcolorspan[] fgspans = spannablestring.getspans(i, next, foregroundcolorspan.class); if (fgspans.length > 0) { int savecolor = mtextpaint.getcolor(); mtextpaint.setcolor(fgspans[0].getforegroundcolor()); canvas.drawtext(spannablestring, i, next, xstart, 0, mtextpaint); mtextpaint.setcolor(savecolor); } else { canvas.drawtext(spannablestring, i, next, xstart, 0, mtextpaint); } xstart = xend; }
the top string in image below drawn code above. bottom string drawn regular textview
(which uses staticlayout
).
Comments
Post a Comment