4

I have a TextView that will hold a styled, multiline string. This text is generated line by line as the data is drawn from different sources bit by bit. As I grab each field, I add a Bold header to the TextView on a new line, then I add the data for that field in italics on a new line.

Example formatting:

Due Date
July 22, 2010
Course
CSC 350

I could set the styling like this:

Spannable str = (Spannable) textview.getText();

str.setSpan(new StyleSpan(android.graphics.Typeface.Bold), 0, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new StyleSpan(android.graphics.Typeface.Italic), 8, 21, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new StyleSpan(android.graphics.Typeface.Bold), 21, 27, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new StyleSpan(android.graphics.Typeface.Italic), 27, 33, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

But that requires knowing the length of each section of text at runtime which is simply unmanageable since there is a variable number of data fields that could be added to the textview.

How can I add the styling as I'm adding each piece of text instead of after all the text has been added?

CodeFusionMobile
  • 14,812
  • 25
  • 102
  • 140

6 Answers6

3

Mark your string up with <b> and <i> tags as appropriate and then use the Html.fromHtml(String) to return the Spannable you are looking for.

jqpubliq
  • 11,874
  • 2
  • 34
  • 26
  • If you're getting the styled string from a resource, this other answer will be useful: http://stackoverflow.com/questions/3235131/set-textview-text-from-html-formatted-string-resource-in-xml – Pierre-Luc Paour Aug 21 '11 at 11:42
3

Html.fromHtml(String) carries a lot more baggage with it than the more light weight SpannableString classes. Whenever possible I would recommend that you avoid fromHtml to style a string.

In your case you could build the string with SpannableStringBuilder and then set the TextView text with the final styled string.

// set the text
SpannableString s1 = new SpannableString("Due Date\n");
SpannableString s2 = new SpannableString("July 22, 2010\n");
SpannableString s3 = new SpannableString("Course\n");
SpannableString s4 = new SpannableString("CSC 350\n");

// set the style
s1.setSpan(new StyleSpan(Typeface.BOLD), 0, s1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
s2.setSpan(new StyleSpan(Typeface.ITALIC), 0, s2.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
s3.setSpan(new StyleSpan(Typeface.BOLD), 0, s3.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
s4.setSpan(new StyleSpan(Typeface.ITALIC), 0, s4.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

// build the string
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(s1);
builder.append(s2);
builder.append(s3);
builder.append(s4);

// set the text view with the styled text
textView.setText(builder);

I set the text and styles one by one but in real usage this could easily be done in a loop. Here is the result:

enter image description here

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
0

I know this question is somewhat old but as it is the top on google, I'd like to throw in the developer page as a good resource for this. The bottom contains suggestions for helper methods to style your text programatically.

Eagle
  • 153
  • 4
0

you can use this:

textview.setTypeface(null, Typeface.BOLD_ITALIC);
Yogesh
  • 1
0

You can set a Spannable as the text of the TextView. That way you can create your text first, add style info when needed, and put that into the TextView as appropriate.

Paul de Vrieze
  • 4,888
  • 1
  • 24
  • 29
0

You should check how HTML class does it. I would parse the input and generate the spannable on the fly.

charroch
  • 2,170
  • 2
  • 15
  • 14