Ich möchte eine SpannedString
auf eine Canvas
zeichnen.Wie zeichne ich eine übergreifende Zeichenfolge mit Canvas.drawText in Android
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);
Das obige Beispiel wurde ein TextView
gezogen Verwendung, die wiederum ein Layout
verwendet, um Text mit Spannweiten zu ziehen. Ich weiß, dass using a Layout
is the recommended way Text auf die Leinwand zeichnen. Allerdings mache ich mein eigenes Textlayout von Grund auf neu, also muss ich das selbst implementieren.
tun so etwas wie dieses nicht
canvas.drawText(spannableString, 0, spannableString.length(), 0, 0, mTextPaint);
funktioniert, weil drawText
nur den Text aus dem spannableString
wird, keine der Spannweiten. Die Zeichnungsfarben werden separat von TextPaint
behandelt.
Wie verwende ich canvas.drawText
(oder drawTextRun
), um die Span Informationen (speziell Vordergrund und Hintergrundfarbe hier) zu zeichnen?
Verwandte
- 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 für eine Lösung
Ich wollte direkt eine Selbst Antwort zu tun, aber das erweist sich als zu mehr diff Schwieriger als ich dachte. Also werde ich zuerst posten und dann eine Antwort hinzufügen, wann immer ich es herausfinden kann. (Ich würde es begrüßen, natürlich jemand zuerst zu beantworten.)
Hier sind die Stücke, die ich bisher haben:
- Draw each span range as a separate text run
- Verwenden
drawTextRun
den Text zu zeichnen (examples) (Update : nicht hinzugefügt bis API 23) - Verwenden Sie
getRunAdvance
, um zu messen, wo der nächste Textlauf zu starten ist (Update: nicht hinzugefügt, bis API 23, verwendenmeasureText
statt) - Die Hintergrundfarbe muss wahrscheinlich separat gezeichnet werden (mit
drawRect
oder vielleichtdrawPath
? Siehe here, here und here.) - Quellcode für
TextView
,StaticLayout
undTextLine
so was ist das Problem mit 'Layout # draw' eigentlich? – pskink
@pskink, der Standard 'Layout' verarbeitet nur horizontalen LTR- und RTL-Text. Ich mache ein vertikales Textlayout für [traditionelles mongolisches] (http://stackoverflow.com/q/29739720/3681880). Ich habe in der Vergangenheit verschiedene [Layout-Hacks] (http://stackoverflow.com/a/29739721/3681880) ausprobiert, aber selbst diese erlauben mir nicht, Emoji oder CJK-Zeichen zu drehen. Also fange ich bei Null an. [Ich habe die grundlegende Layout-Funktionalität abgeschlossen] (https://github.com/suragch/mongoll-library/blob/master/mongoll-library/src/main/java/net/studymongolian/mongollibrary/MongolLayout.java); Jetzt muss ich übergreifenden Text unterstützen. – Suragch
ok, jetzt sehe ich, dass es kein "normales" 'Hallo Welt' ist, das du in deinem Bild – pskink