How to Have Multiple Styles Inside a Textview

Is it possible to have multiple styles inside a TextView?

In case, anyone is wondering how to do this, here's one way: (Thanks to Mark again!)

mBox = new TextView(context);
mBox.setText(Html.fromHtml("<b>" + title + "</b>" + "<br />" +
"<small>" + description + "</small>" + "<br />" +
"<small>" + DateAdded + "</small>"));

For an unofficial list of tags supported by this method, refer to this link or this question: Which HTML tags are supported by Android TextView?

wants to have multiple text display styles in a single textview

Say, you have a TextView namely etx, use the following code:


 final SpannableStringBuilder sb = new SpannableStringBuilder("HELLOO");

final StyleSpan bss = new StyleSpan(android.graphics.Typeface.BOLD); // Span to make text bold
final StyleSpan iss = new StyleSpan(android.graphics.Typeface.ITALIC);Span to make text italic
sb.setSpan(bss, 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
sb.setSpan(iss, 4, 6, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make last 2 characters Italic
etx.setText(sb);

The main advantage of using this approach is that you can format text dynamically.

Two different styles in a single textview with different gravity and height

I cracked it. I am posting this as it might be helpful for others and thanks to @kcoppock for the hint.
I have extended MetricAffectingSpan class which affects character-level text formatting in a way that changes the width or height of characters extend this class.

public class CustomCharacterSpan extends MetricAffectingSpan {
double ratio = 0.5;

public CustomCharacterSpan() {
}

public CustomCharacterSpan(double ratio) {
this.ratio = ratio;
}

@Override
public void updateDrawState(TextPaint paint) {
paint.baselineShift += (int) (paint.ascent() * ratio);
}

@Override
public void updateMeasureState(TextPaint paint) {
paint.baselineShift += (int) (paint.ascent() * ratio);
}}

use this to update the text in your views..

String string = tv.getText().toString();
SpannableString text = new SpannableString(tv.getText());
int index = tv.getText().toString().indexOf(".");
text.setSpan(new CustomCharacterSpan(), index, string.length(),
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);//u can use ur own ratio using another constructor
tv.setText(text, TextView.BufferType.SPANNABLE);

multiple style values inside a view

You can't. You will have to create a style which combines the two styles. (Or create just one style that inherits from one of your styles, and add the extra data of the second style).

Apply two different font styles to a TextView

One way to do this is to extend TypefaceSpan:

import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.TypefaceSpan;

public class CustomTypefaceSpan extends TypefaceSpan {
private final Typeface newType;

public CustomTypefaceSpan(String family, Typeface type) {
super(family);
newType = type;
}

@Override
public void updateDrawState(TextPaint ds) {
applyCustomTypeFace(ds, newType);
}

@Override
public void updateMeasureState(TextPaint paint) {
applyCustomTypeFace(paint, newType);
}

private static void applyCustomTypeFace(Paint paint, Typeface tf) {
int oldStyle;
Typeface old = paint.getTypeface();
if (old == null) {
oldStyle = 0;
} else {
oldStyle = old.getStyle();
}

int fake = oldStyle & ~tf.getStyle();
if ((fake & Typeface.BOLD) != 0) {
paint.setFakeBoldText(true);
}

if ((fake & Typeface.ITALIC) != 0) {
paint.setTextSkewX(-0.25f);
}

paint.setTypeface(tf);
}
}

Then when you want to use two different typefaces call:

String firstWord = "first ";
String secondWord = "second";

// Create a new spannable with the two strings
Spannable spannable = new SpannableString(firstWord+secondWord);

// Set the custom typeface to span over a section of the spannable object
spannable.setSpan( new CustomTypefaceSpan("sans-serif",CUSTOM_TYPEFACE), 0, firstWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan( new CustomTypefaceSpan("sans-serif",SECOND_CUSTOM_TYPEFACE), firstWord.length(), firstWord.length() + secondWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

// Set the text of a textView with the spannable object
textView.setText( spannable );

Android format TextView with multiple styles

You can use the spannable style classes:

final SpannableStringBuilder sb = new SpannableStringBuilder("Hello World 123456");

sb.setSpan(new StyleSpan(Typeface.BOLD), 0, 7, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
sb.setSpan(new StyleSpan(Typeface.ITALIC), 7, 14, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
sb.setSpan(new ForegroundColorSpan(), 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
sb.setSpan(new UnderlineSpan(), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sb.setSpan(new SuperscriptSpan(), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

textView.setText(sb);

Follow the link to get the full list of ParcelableSpan subclasses:

https://developer.android.com/reference/android/text/ParcelableSpan



Related Topics



Leave a reply



Submit