Spannablestringbuilder to Create String with Multiple Fonts/Text Sizes etc Example

SpannableStringBuilder to create String with multiple fonts/text sizes etc Example?

First Part Not Bold   BOLD  rest not bold

You can do this either as @Rajesh suggested or by this.

String normalBefore= "First Part Not Bold ";
String normalBOLD= "BOLD ";
String normalAfter= "rest not bold";
String finalString= normalBefore+normalBOLD+normalAfter;
Spannable sb = new SpannableString( finalString );
sb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), finalString.indexOf(normalBOLD)+ normalBOLD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //bold
sb.setSpan(new AbsoluteSizeSpan(intSize), finalString.indexOf(normalBOLD)+ normalBOLD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//resize size

to show this in TextView

textview.setText(sb,  TextView.BufferType.SPANNABLE);

Different font size of strings in the same TextView

Use a Spannable String

 String s= "Hello Everyone";
SpannableString ss1= new SpannableString(s);
ss1.setSpan(new RelativeSizeSpan(2f), 0,5, 0); // set size
ss1.setSpan(new ForegroundColorSpan(Color.RED), 0, 5, 0);// set color
TextView tv= (TextView) findViewById(R.id.textview);
tv.setText(ss1);

Snap shot

Sample Image

You can split string using space and add span to the string you require.

 String s= "Hello Everyone";  
String[] each = s.split(" ");

Now apply span to the string and add the same to textview.

Making multiple parts of a SpannableStringBuilder Bold

Use two different spans:

val builder = SpannableStringBuilder()
val spanFlag = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE

builder.append("BOLD ", StyleSpan(Typeface.BOLD), spanFlag)
builder.append("not bold ")
builder.append("BOLD ", StyleSpan(Typeface.BOLD), spanFlag)
builder.append("not bold ")

return builder

SpannableStringBuilder setting String partially as bold not working

The specified code looks to be working well as visible in the screenshot here: https://imgur.com/a/1cOLQrC

Please check your code for other mistakes causing wrong behavior.

Spannable String Builder not applying font

You can use this custom TypefaceSpan class:

class CustomTypefaceSpan constructor(type: Typeface) : TypefaceSpan("") {

private var newType = type

override fun updateDrawState(ds: TextPaint) {
applyCustomTypeFace(ds, newType)
}

override fun updateMeasureState(paint: TextPaint) {
applyCustomTypeFace(paint, newType)
}

private fun applyCustomTypeFace(paint: Paint, tf: Typeface?) {
val old: Typeface = paint.typeface
val oldStyle = old.style
val fake = oldStyle and tf!!.style.inv()
if (fake and Typeface.BOLD != 0) paint.isFakeBoldText = true
if (fake and Typeface.ITALIC != 0) paint.textSkewX = -0.25f
paint.typeface = tf
}

}

And apply that to your the SpannableStringBuilder:

private fun createSpannedNameAndComment(name: String, comment: String): SpannableStringBuilder {

val semiBoldFont = android.graphics.Typeface.create(
ResourcesCompat.getFont(
this,
R.font.josefin_san_semi_bold
), android.graphics.Typeface.NORMAL
)

val regularFont = android.graphics.Typeface.create(
ResourcesCompat.getFont(
this,
R.font.josefin_san_regular
), android.graphics.Typeface.NORMAL
)

return SpannableStringBuilder().apply {
append(name, CustomTypefaceSpan(semiBoldFont), 0)
append(" ")
append(comment, CustomTypefaceSpan(regularFont), 0)
}

}

How to have a SpannableStringBuilder append a span that's inside a formatted string?

OK, I've found an answer to my special end case, but I'd still like to know if there are better ways.

Here's what I did:

String stringToSearchAt=...
String query=...
int queryIdx = stringToSearchAt.toLowerCase().indexOf(query);
stringToSearchAt= stringToSearchAt.substring(0, queryIdx + query.length()) + "<bc/>" + stringToSearchAt.substring(queryIdx + query.length());
final String formattedStr=getString(..., stringToSearchAt);
stringBuilder.append(Html.fromHtml(formattedStr, null, new TagHandler() {
int start;

@Override
public void handleTag(final boolean opening, final String tag, Editable output, final XMLReader xmlReader) {
switch (tag) {
case "bc":
if (!opening)
start = output.length() - query.length();
break;
case "html":
if (!opening)
output.setSpan(new BackgroundColorSpan(0xff00bbaa), start, start + query.length(), 0);
}
}
}));

This is only good for my case, but in the case of general formatting, this won't suffice.

Can multiple setSpan be applied to the same SpannableStringBuilder?

Instead of SpannableStringBuilder I use SpannableString and it works fine.

Try to this code:

SpannableString sentence = new SpannableString(sb.toString());

and then

tvText.setText(sentence);

SpannableStringBuilder setSpan doesn't work on Arabic text

Use Calligraphy instead of PixUI. Here is the Gradle dependecy for it:

compile 'uk.co.chrisjenx:calligraphy:2.1.0'

Use TextView not some custom TextView like PixUI TextView.

<TextView
android:id="@+id/sura"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/kuran_sure_text_size"
android:textDirection="rtl"/>

Apply custom font after building resulting text:

SpannableStringBuilder ssb = new SpannableStringBuilder();

for (int i = 0; i < contentJsonArray.length(); ++i) {
JSONObject json = (JSONObject)contentJsonArray.get(i);
ssb.append(json.getString(KEY_SOME_KEY));

if (i == contentJsonArray.length() - 1)
break;

int start = ssb.length();
ssb.append("( # )");
ssb.setSpan(new ForegroundColorSpan(R.color.Red), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.setSpan(new AbsoluteSizeSpan(10, true), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

CalligraphyTypefaceSpan typefaceSpan =
new CalligraphyTypefaceSpan(
TypefaceUtils.load(getActivity().getAssets(),
"fonts/some_custom_font.ttf"));
ssb.setSpan(typefaceSpan, 0, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(ssb);

Use color code for ForegroundColorSpan like 0xAARRGGBB as @pskink suggested:

ssb.setSpan(new ForegroundColorSpan(0xFFFF0000), start, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);


Related Topics



Leave a reply



Submit