how to make a specific text on TextView BOLD
Asked Answered
M

31

370

I don't know how to make a specific text on TextView become BOLD.

its like this

txtResult.setText(id+" "+name);

I want the output to be like this:

1111 neil

id and name are variables that I have retrieved the value from database, and I want to make the id to bold, but only the id so the name will not affected, I have no idea how to do this.

Mischief answered 17/1, 2013 at 2:2 Comment(1)
Possible duplicate of Is it possible to have multiple styles inside a TextView?Fineness
T
466

Just build your String in HTML and set it:

String sourceString = "<b>" + id + "</b> " + name; 
mytextview.setText(Html.fromHtml(sourceString));
Tinctorial answered 17/1, 2013 at 2:4 Comment(11)
As fromHtml( sourceString) is deprecated in API 24 , you have to use next code : Spanned durationSpanned; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { durationSpanned = Html.fromHtml(durationFormatted,Html.FROM_HTML_MODE_LEGACY); } else { durationSpanned = Html.fromHtml(durationFormatted); }Marthena
This is the only option that will work if you are localizing your app.Tanjatanjore
Its a good solution but I found out it doesn't work for < and > @wtsang02 solution is more optimalBasilica
It don't work with < IF you use String.format, UNLESS you also escape the bracket, as described here.Ddene
Html.fromHtml() is now deprecatedDisney
It doesn't work if you have a custom font applied to a TextViewKearse
It's not slow if the text is smallPainter
Using HTML to style your text in your TextView is not good practice, it is very taxing your machine. Kotlin has introduced buildSpannedString{}, please use that.Hypogeous
you can use text.text = HtmlCompat.fromHtml( ctx.getString(R.string.logout_confirm), HtmlCompat.FROM_HTML_MODE_COMPACT )Gory
Now setting android:text="@string/some_html_text" and <string name="some_html_text">Some <b>HTML</b>: text</string> will show bold without HtmlCompat.fromHtml().Moline
@MahmoudMabrok your solution not working anymoreLoginov
I
458

While you can use Html.fromHtml() you can use a more native approach which is SpannableStringBuilder , this post may be helful.

SpannableStringBuilder str = new SpannableStringBuilder("Your awesome text");
str.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), INT_START, INT_END, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TextView tv=new TextView(context);
tv.setText(str);
Irate answered 17/1, 2013 at 2:9 Comment(8)
If this answer doesn't works try to append your text with spannable string some thing like : mSpannable.append(yourremainingtext);Ennui
For people coming from Google with no prior knowledge: INT_START/INT_END are the location on where the bold should start and end.Mispleading
if you only need to apply some markup to the source string without changing it, then you you better use SpannableString classBiquadrate
This will completely break if you need to localize your copy. INT_START and INT_END will be different positions in different localizations.Tanjatanjore
Didn't work out. I'm getting Cannot Resolve INT_END errorSassan
Try to understand what the code is doing when in doubt. The int start is a number you define, which is the start index of the span. Try 0 for start, string.().size() for end.Irate
For a more concise syntax for spannables, refer this: https://mcmap.net/q/92264/-how-to-make-a-specific-text-on-textview-boldGleiwitz
Use SpannableString instead of SpannableStringBuilderAsterism
B
218

First: You don't need to worry about using the slow performance code from the Raghav Sood's answer.

Second: You don't need to write an extension function provided by w3bshark's answer when using Kotlin.

Finnaly: All you need to do is to use the Kotlin android-ktx library from Google (refer here to find more information and how to include it on your project):

// Suppose id = 1111 and name = neil (just what you want). 
val s = SpannableStringBuilder()
          .bold { append(id) } 
          .append(name)
txtResult.setText(s) 

Produces: 1111 neil


UPDATE:

Because I think it can help someone else as well as to demonstrate how far you can go here are more use cases.

  • When you need to display a text with some parts in blue and italic:

    val myCustomizedString = SpannableStringBuilder()
        .color(blueColor, { append("A blue text ") })
        .append("showing that ")
        .italic{ append("it is painless") }
    
  • When you need to display a text in both bold and italic:

        bold { italic { append("Bold and italic") } }
    

In short, bold, append, color and italic are extension functions to SpannableStringBuilder. You can see another extension functions in the official documentation, from where you can think for other possibilities.

Bracket answered 9/5, 2018 at 0:17 Comment(3)
This is great and all but I think every answer related to strings should consider translations. Words in sentences can be ordered and structured completely differently in some languages so appending like this isn't always applicable in certain situations. Also not ideal for stuff like quantity strings in XML.Reign
@Moline It doesn't make you unable to use Android KTX. You can find information from github.com/android/android-ktx on how to bug report, make a feature suggestion or contribute to that library. So, it is still a valid reference. I've updated my answer to include more information about the library and how to use it on your project.Bracket
Using this solution I have created a kotlin extension function, It might be helpful: gist.github.com/muazdev26/124f7a5ff28d78fcddb492965b85478eRebeckarebeka
B
41

I thought that the chosen answer didn't provide a satisfactory result. I have written my own function which takes 2 strings; The full text and the part of the text you want to make bold.

It returns a SpannableStringBuilder with the 'textToBold' from 'text' bolded.

I find the ability to make a substring bold without wrapping it in tags useful.

    /**
     * Makes a substring of a string bold.
     * @param text          Full text
     * @param textToBold    Text you want to make bold
     * @return              String with bold substring
     */

    public static SpannableStringBuilder makeSectionOfTextBold(String text, String textToBold){

        SpannableStringBuilder builder=new SpannableStringBuilder();

        if(textToBold.length() > 0 && !textToBold.trim().equals("")){

            //for counting start/end indexes
            String testText = text.toLowerCase(Locale.US);
            String testTextToBold = textToBold.toLowerCase(Locale.US);
            int startingIndex = testText.indexOf(testTextToBold);
            int endingIndex = startingIndex + testTextToBold.length();
            //for counting start/end indexes

            if(startingIndex < 0 || endingIndex <0){
                return builder.append(text);
            }
            else if(startingIndex >= 0 && endingIndex >=0){

                builder.append(text);
                builder.setSpan(new StyleSpan(Typeface.BOLD), startingIndex, endingIndex, 0);
            }
        }else{
            return builder.append(text);
        }

        return builder;
  }
Bellbella answered 15/7, 2014 at 9:8 Comment(5)
Can you provide an example of how to use this in code?Scheming
@MicroR You need to pass two Strings, the second String needs to be a section of text contained within the first. e.g. makeSectionOfTextBold("This is some great text.", "great").Shellback
you should change your if statement with if(textToBold != null && !textToBold.isEmpty())Euthenics
This function does not expect the substring can occur in full text multiple times. For example in "My username is name" it cannot make the 2nd "name" bold.Streetcar
Then this method should actually be named makeAllBold(text,textToBold).Irate
S
40

As wtsang02 said, using HTML is an expensive overhead. Just use the native solution. If you don't have to modify the string, just use SpannableString, not SpannableStringBuilder.

String boldText = "id";
String normalText = "name";
SpannableString str = new SpannableString(boldText + normalText);
str.setSpan(new StyleSpan(Typeface.BOLD), 0, boldText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(str);
Streetcar answered 4/1, 2017 at 9:31 Comment(0)
B
37

In case you want to use the string from XML, you can do something like this:

strings.xml (the "CDATA" part is important, otherwise it won't work)

<string name="test">
     <![CDATA[
 <b>bold!</b> normal
    ]]>
</string>

layout file

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_gravity="center" />

</FrameLayout>

code

textView.text = HtmlCompat.fromHtml(getString(R.string.test), HtmlCompat.FROM_HTML_MODE_LEGACY)
Bauer answered 1/2, 2017 at 10:4 Comment(1)
@androiddeveloper I use the flag HtmlCompat.FROM_HTML_MODE_COMPACT. It works fine too.Erhart
D
25

Its simple just close the specified text like this for example <b>"your text here:"</b>

<string name="headquarters">"<b>"Headquarters:"</b>" Mooresville, North Carolina, U.S.</string>

result: Headquarters: Mooresville, North Carolina, U.S.

Duleba answered 4/8, 2017 at 14:28 Comment(1)
This only works if string is used from xml. If this string is called programmatically, the html encoding gets stripped away.Cung
G
21

If you are using Kotlin, it becomes even easier to do by using core-ktx, as it provides a domain-specific-language (DSL) for doing this:

val string: SpannedString = buildSpannedString {
    bold {
        append("foo")
    }
    append("bar")     
}

More options provided by it are:

append("Hello There")
bold {
    append("bold")
    italic {
        append("bold and italic")
        underline {
            append("then some text with underline")
        }
    }
}

At last, you can just to:

textView.text = string
Gleiwitz answered 27/6, 2019 at 0:46 Comment(0)
D
14

Based on @mladj0ni's answer, I got the code below to work. The problem was that if you use String.format, it strips out the html markup, so you have to escape the bracket symbols in strings.xml:

strings.xml:

<string name="welcome_messages">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>

code.java:

String unspanned = String.format(Locale.US, "%s%s", getResources().getString(R.string. welcome_messages), 99);

Spanned spanned;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
    spanned = Html.fromHtml(unspanned, Html.FROM_HTML_MODE_LEGACY);
} else {
    spanned = Html.fromHtml(unspanned);
}

textView.setText(spanned);

It's simpler than SpannableStringBuilder. As for performance, if you're displaying just one string, then the user won't notice the extra millisecond to parse it.

See the documentation here.

Ddene answered 17/7, 2017 at 23:19 Comment(0)
T
11

Here is better solution if you want to make multiple text to bold. I've improved Eitan's code. thanks Eitan.

public static SpannableStringBuilder makeSectionOfTextBold(String text, String... textToBold) {
    SpannableStringBuilder builder = new SpannableStringBuilder(text);

    for (String textItem :
            textToBold) {
        if (textItem.length() > 0 && !textItem.trim().equals("")) {
            //for counting start/end indexes
            String testText = text.toLowerCase(Locale.US);
            String testTextToBold = textItem.toLowerCase(Locale.US);
            int startingIndex = testText.indexOf(testTextToBold);
            int endingIndex = startingIndex + testTextToBold.length();

            if (startingIndex >= 0 && endingIndex >= 0) {
                builder.setSpan(new StyleSpan(Typeface.BOLD), startingIndex, endingIndex, 0);
            }
        }
    }

    return builder;
}
Towboat answered 23/8, 2016 at 6:45 Comment(0)
D
9

You can use this code to set part of your text to bold. For whatever is in between the bold html tags, it will make it bold.

String myText = "make this <b>bold</b> and <b>this</b> too";
textView.setText(makeSpannable(myText, "<b>(.+?)</b>", "<b>", "</b>"));

public SpannableStringBuilder makeSpannable(String text, String regex, String startTag, String endTag) {

            StringBuffer sb = new StringBuffer();
            SpannableStringBuilder spannable = new SpannableStringBuilder();

            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(text);
            while (matcher.find()) {
                sb.setLength(0);
                String group = matcher.group();
                String spanText = group.substring(startTag.length(), group.length() - endTag.length());
                matcher.appendReplacement(sb, spanText);

                spannable.append(sb.toString());
                int start = spannable.length() - spanText.length();

                spannable.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), start, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            sb.setLength(0);
            matcher.appendTail(sb);
            spannable.append(sb.toString());
            return spannable;
        }
Desexualize answered 24/8, 2018 at 19:7 Comment(0)
S
7

wtsang02 answer is the best way to go about it, since, Html.fromHtml("") is now deprecated. Here I'm just going to enhance it a little bit for whoever is having problem in dynamically making the first word bold, no matter whats the size of the sentence.

First lets create a method to get the first word:

 private String getFirstWord(String input){

    for(int i = 0; i < input.length(); i++){

        if(input.charAt(i) == ' '){

            return input.substring(0, i);
        }
    }

    return input;
}

Now let's say you have a long string like this:

String sentence = "[email protected] want's to be your friend!"

And you want your sentence to be like [email protected] want's to be your friend! All you have to do is- get the firstWord and get the lenght of it to make the firstWord bold, something like this:

String myFirstWord = getFirstWord(sentence);
int start = 0; // bold will start at index 0
int end = myFirstWord.length(); // and will finish at whatever the length of your first word

Now just follow wtsang02 's steps, like this:

SpannableStringBuilder fancySentence = new SpannableStringBuilder(sentence);
fancySentence.setSpan(new android.text.style.StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(fancySentence);

And that's it! Now you should be able to bold a word with any size from long/short sentence.

Silk answered 13/11, 2018 at 3:2 Comment(0)
N
5

Isn't this code the easiest solution?

<string name="string">Please provide your <b>Name</b> properly</string>

Just use this string whatever you want :)

The result will like this:

Please provide your Name properly

Nibelungenlied answered 21/2, 2022 at 3:43 Comment(3)
This solution only works if we set string resources on XML. like: <TextView ... ... android:text="@string/string" /> But it failed when we set the string resource programmatically. Like: textView.text = resources.getString(R.string.string)Temperamental
Programatically, we have to call setText(R.string.someStringId) instead of using property syntax like textView.text=getString(R.string.someStringId) @Md.ArifKnighterrantry
@RamakrishnaJoshi it does not make any difference at allLoginov
A
4

I came here to provide a more up-to-date solution, because I wasn't satisfied with the existing answers. I needed something that would work for translated texts and does not have the performance hit of using Html.fromHtml(). If you're using Kotlin, here is an extension function which will easily set multiple parts of your text to bold. This works just like Markdown, and could be extended to support other Markdown tags, if need be.

val yourString = "**This** is your **string**.".makePartialTextsBold()
val anotherString = getString(R.string.something).makePartialTextsBold()

/**
 * This function requires that the parts of the string that need
 * to be bolded are wrapped in ** and ** tags
 */
fun String.makePartialTextsBold(): SpannableStringBuilder {
    var copy = this
    return SpannableStringBuilder().apply {
        var setSpan = true
        var next: String
        do {
            setSpan = !setSpan
            next = if (length == 0) copy.substringBefore("**", "") else copy.substringBefore("**")
            val start = length
            append(next)
            if (setSpan) {
                setSpan(StyleSpan(Typeface.BOLD), start, length,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            }
            copy = copy.removePrefix(next).removePrefix("**")
        } while (copy.isNotEmpty())
    }
}
Aubrette answered 14/1, 2018 at 18:12 Comment(0)
S
4

Here is my complete solution for dynamic String values with case check.

/**
 * Makes a portion of String formatted in BOLD.
 *
 * @param completeString       String from which a portion needs to be extracted and formatted.<br> eg. I am BOLD.
 * @param targetStringToFormat Target String value to format. <br>eg. BOLD
 * @param matchCase Match by target character case or not. If true, BOLD != bold
 * @return A string with a portion formatted in BOLD. <br> I am <b>BOLD</b>.
 */
public static SpannableStringBuilder formatAStringPortionInBold(String completeString, String targetStringToFormat, boolean matchCase) {
    //Null complete string return empty
    if (TextUtils.isEmpty(completeString)) {
        return new SpannableStringBuilder("");
    }

    SpannableStringBuilder str = new SpannableStringBuilder(completeString);
    int start_index = 0;

    //if matchCase is true, match exact string
    if (matchCase) {
        if (TextUtils.isEmpty(targetStringToFormat) || !completeString.contains(targetStringToFormat)) {
            return str;
        }

        start_index = str.toString().indexOf(targetStringToFormat);
    } else {
        //else find in lower cases
        if (TextUtils.isEmpty(targetStringToFormat) || !completeString.toLowerCase().contains(targetStringToFormat.toLowerCase())) {
            return str;
        }

        start_index = str.toString().toLowerCase().indexOf(targetStringToFormat.toLowerCase());
    }

    int end_index = start_index + targetStringToFormat.length();
    str.setSpan(new StyleSpan(BOLD), start_index, end_index, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return str;
}

Eg. completeString = "I am BOLD"

CASE I if *targetStringToFormat* = "bold" and *matchCase* = true

returns "I am BOLD" (since bold != BOLD)

CASE II if *targetStringToFormat* = "bold" and *matchCase* = false

returns "I am BOLD"

To Apply:

myTextView.setText(formatAStringPortionInBold("I am BOLD", "bold", false))

Hope that helps!

Sezen answered 13/6, 2018 at 6:3 Comment(0)
M
4

I used this code to bold specific words...

    Spanned string = Html.fromHtml("Normal string <b>BOLD STRING</b>");
    textView.setText(string);
Melodize answered 9/11, 2020 at 4:4 Comment(0)
S
3
public static Spanned getBoldString(String textNotBoldFirst, String textToBold, String textNotBoldLast) {
    String resultant = null;

    resultant = textNotBoldFirst + " " + "<b>" + textToBold + "</b>" + " " + textNotBoldLast;

    return Html.fromHtml(resultant);

}

Try this. It can help definitely

Sweater answered 21/8, 2016 at 16:16 Comment(0)
S
3

Make first char of string spannable while searching for char in list/recycler like

ravi and ajay

previously highlighting like this but i wanted to be like below

ravi and ajay OR ravi and ajay

for this I searched for word length if it is equal to 1 ,I separated main string into words and calculated word start position then I searched word starting with char.

 public static SpannableString colorString(int color, String text, String... wordsToColor) {
    SpannableString coloredString = new SpannableString(text);

    for (String word : wordsToColor) {

        Log.e("tokentoken", "-wrd len-" + word.length());
        if (word.length() !=1) {
            int startColorIndex = text.toLowerCase().indexOf(word.toLowerCase());
            int endColorIndex = startColorIndex + word.length();
            try {
                coloredString.setSpan(new ForegroundColorSpan(color), startColorIndex, endColorIndex,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            } catch (Exception e) {
                e.getMessage();
            }
        } else {
            int start = 0;

            for (String token : text.split("[\u00A0 \n]")) {
                if (token.length() > 0) {
                    start = text.indexOf(token, start);
                   // Log.e("tokentoken", "-token-" + token + "   --start--" + start);
                    char x = token.toLowerCase().charAt(0);
                    char w = word.toLowerCase().charAt(0);
                   // Log.e("tokentoken", "-w-" + w + "   --x--" + x);

                    if (x == w) {
                        // int startColorIndex = text.toLowerCase().indexOf(word.toLowerCase());
                        int endColorIndex = start + word.length();
                        try {
                            coloredString.setSpan(new ForegroundColorSpan(color), start, endColorIndex,
                                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

                        } catch (Exception e) {
                            e.getMessage();
                        }
                    }
                }
            }

        }

    }

    return coloredString;
}
Submultiple answered 30/11, 2017 at 10:54 Comment(0)
T
3

You can add the two strings separately in the builder, one of them is spannedString, the other is a regular one.This way you don`t have to calculate the indexes.

val instructionPress = resources?.getString(R.string.settings_press)

val okText = resources?.getString(R.string.ok)
val spannableString = SpannableString(okText)

val spannableBuilder = SpannableStringBuilder()
spannableBuilder.append(instructionPress)
spannableBuilder.append(spannableString, StyleSpan(Typeface.BOLD), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

instructionText.setText(spannableBuilder,TextView.BufferType.SPANNABLE)
Torrell answered 10/5, 2018 at 8:52 Comment(0)
E
3

This is the Kotlin extension function I use for this

/**
 * Sets the specified Typeface Style on the first instance of the specified substring(s)
 * @param one or more [Pair] of [String] and [Typeface] style (e.g. BOLD, ITALIC, etc.)
 */
fun TextView.setSubstringTypeface(vararg textsToStyle: Pair<String, Int>) {
    val spannableString = SpannableString(this.text)
    for (textToStyle in textsToStyle) {
        val startIndex = this.text.toString().indexOf(textToStyle.first)
        val endIndex = startIndex + textToStyle.first.length

        if (startIndex >= 0) {
            spannableString.setSpan(
                StyleSpan(textToStyle.second),
                startIndex,
                endIndex,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
        }
    }
    this.setText(spannableString, TextView.BufferType.SPANNABLE)
}

Usage:

text_view.text="something bold"
text_view.setSubstringTypeface(
    Pair(
        "something bold",
        Typeface.BOLD
    )
)

.

text_view.text="something bold something italic"
text_view.setSubstringTypeface(
    Pair(
        "something bold ",
        Typeface.BOLD
    ),
    Pair(
        "something italic",
        Typeface.ITALIC
    )
)
Erasmo answered 24/5, 2019 at 15:7 Comment(0)
Y
2

if the position of bold text is fixed(ex: if is at start of the textView), then use two different textView with same background. Then you can make the other textView's textStyle as bold.

This will require twice the memory compared to a single textView but speed will increase.

Yoshieyoshiko answered 16/6, 2018 at 9:40 Comment(0)
S
2

Found a way in case you want to handle localization in multiple languages, it's boring to do but it works, let's suppose we want this:

In English:

There are no payments registered

In Spanish:

No hay pagos registrados

You have to create 3 strings

English:

<string name="start_string">There are no</string>
<string name="middle_string">payments</string>
<string name="end_string">registered.</string>
<string name="string_format" translatable="false">%1$s %2$s %3$s</string>

Spanish:

<string name="start_string">No hay</string>
<string name="middle_string">pagos</string>
<string name="end_string">registrados</string>

Now you can do this:

val startSpanPosition = getString(R.string.start_string).length
val endSpanPosition = startSpanPosition + getString(R.string.middle_string).length
val mySpannableString = SpannableStringBuilder(String.format(getString(R.string.string_format),
        getString(R.string.start_string), getString(R.string.middle_string))), getString(R.string.end_string)))

mySpannableString.setSpan(StyleSpan(Typeface.BOLD), spanStartPosition, endSpanPosition, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
Soonsooner answered 27/4, 2020 at 17:34 Comment(0)
S
2

Your String resource

<resources>
   <string name="your_string_resource_name">This is normal text<![CDATA[<b> but this is bold </b>]]> and <![CDATA[<u> but this is underline text</u>]]></string>
</resources> 

your java class

yourtextView.setText(getString(R.string.your_string_resource_name));
Saccharin answered 29/4, 2020 at 13:59 Comment(0)
Y
1

I have created a static method for setting part of text Bold for TextView and EditText

public static void boldPartOfText(View mView, String contentData, int startIndex, int endIndex){
        if(!contentData.isEmpty() && contentData.length() > endIndex) {
            final SpannableStringBuilder sb = new SpannableStringBuilder(contentData);

            final StyleSpan bss = new StyleSpan(Typeface.BOLD); // Span to make text bold
            final StyleSpan iss = new StyleSpan(Typeface.NORMAL); //Span to make text normal
            sb.setSpan(iss, 0, startIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
            sb.setSpan(bss, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
            sb.setSpan(iss,endIndex, contentData.length()-1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);

            if(mView instanceof TextView)
               ((TextView) mView).setText(sb);
            else if(mView instanceof EditText)
               ((EditText) mView).setText(sb);

        }
    }

Another more customized code

  /*typeFaceStyle can be passed as 

    Typeface.NORMAL = 0;
    Typeface.BOLD = 1;
    Typeface.ITALIC = 2;
    Typeface.BOLD_ITALIC = 3;*/

    public static void boldPartOfText(View mView, String contentData, int startIndex, int endIndex,int typeFaceStyle){
        if(!contentData.isEmpty() && contentData.length() > endIndex) {
            final SpannableStringBuilder sb = new SpannableStringBuilder(contentData);

            final StyleSpan bss = new StyleSpan(typeFaceStyle); // Span to make text bold
            final StyleSpan iss = new StyleSpan(Typeface.NORMAL); //Span to make text italic
            sb.setSpan(iss, 0, startIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
            sb.setSpan(bss, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
            sb.setSpan(iss,endIndex,contentData.length()-1,Spanned.SPAN_INCLUSIVE_INCLUSIVE);

            if(mView instanceof TextView)
                ((TextView) mView).setText(sb);
            else if(mView instanceof EditText)
                ((EditText) mView).setText(sb);
        }
    }
Yolondayon answered 30/5, 2017 at 7:14 Comment(0)
S
1

In case someone is using Data Binding. We can define binding adapter like this

@BindingAdapter("html")
fun setHtml(view: TextView, html: String) {
    view.setText(HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY))
}

Then we can use it on a TextView

app:html="@{@string/bold_text}"

where bold_text is

<string name="bold_text"><![CDATA[Part of text is <b>bold</b>]]></string>
Sisyphus answered 11/10, 2019 at 10:11 Comment(2)
Where do you write the "setHtml" function?Bauer
developer.android.com/topic/libraries/data-binding/… It's basically any class, as long as you have annotationSisyphus
S
1

Simple Example

In you strings.xml

<string name="str_privacy_policy">This is our Privacy Policy.</string>

if you want to make specifically "Privacy Policy" as bold put the string between the bold tags.

Like this

<string name="str_privacy_policy">This is our <b>Privacy Policy.</b></string>

Result would be

This is our Privacy Policy

Sholeen answered 8/10, 2020 at 8:58 Comment(0)
D
1

StringMakeup.kt - Useful Reusable Code for Kotlin

class StringMakeup(input: String) {


    private val sb: Spannable

    private val length: Int
        get() = sb.length

    init {
        sb = SpannableString(input)
    }


    fun strikethrough(start: Int, length: Int): StringMakeup {
        val span = StrikethroughSpan()
        sb.setSpan(span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun strikethrough(): StringMakeup {
        val span = StrikethroughSpan()
        sb.setSpan(span, 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun underline(start: Int, length: Int): StringMakeup {
        val span = UnderlineSpan()
        sb.setSpan(span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun underline(): StringMakeup {
        val span = UnderlineSpan()
        sb.setSpan(span, 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun boldify(start: Int, length: Int): StringMakeup {
        val span = StyleSpan(Typeface.BOLD)
        sb.setSpan(span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun boldify(): StringMakeup {
        val span = StyleSpan(Typeface.BOLD)
        sb.setSpan(span, 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun italize(start: Int, length: Int): StringMakeup {
        val span = StyleSpan(Typeface.ITALIC)
        sb.setSpan(span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun italize(): StringMakeup {
        val span = StyleSpan(Typeface.ITALIC)
        sb.setSpan(span, 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun colorize(start: Int, length: Int, @ColorInt color: Int): StringMakeup {
        val span = ForegroundColorSpan(color)
        sb.setSpan(span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun colorize(@ColorInt color: Int): StringMakeup {
        val span = ForegroundColorSpan(color)
        sb.setSpan(span, 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun mark(start: Int, length: Int, @ColorInt color: Int): StringMakeup {
        val span = BackgroundColorSpan(color)
        sb.setSpan(span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun mark(color: Int): StringMakeup {
        val span = BackgroundColorSpan(color)
        sb.setSpan(span, 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun proportionate(start: Int, length: Int, proportion: Float): StringMakeup {
        val span = RelativeSizeSpan(proportion)
        sb.setSpan(span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun proportionate(proportion: Float): StringMakeup {
        val span = RelativeSizeSpan(proportion)
        sb.setSpan(span, 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        return this
    }


    fun apply(): Spannable {
        return sb
    }
}
Doggy answered 22/10, 2023 at 14:36 Comment(0)
R
0

Here's how I do it using regular expressions and Kotlin

val BOLD_SPAN = StyleSpan(Typeface.BOLD)

    fun TextView.boldMatches(regexString: String) {
        this.applyStyleSpanToMatches(regexString, BOLD_SPAN)
    }
    

fun TextView.applyStyleSpanToMatches(regexString: String, span: StyleSpan){
        this.text = this.text.toString().applyStyleSpanToMatches(regexString, span)
        }

        fun String.applyStyleSpanToMatches(regexString: String, span: StyleSpan): Spannable {
            val result = SpannableString.valueOf(this)
            if(regexString.isEmpty()) return result
            val pattern = try{
                Pattern.compile(regexString)
            } catch (e: PatternSyntaxException){
                return result
            }
            val matcher = pattern.matcher(result)
            while (matcher.find()) {
                val start = matcher.start()
                val end = matcher.end()
                result.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            }
            return result
        }

using the question it can be applied like this:

txtResult.boldMatches(id)
Razorback answered 21/7, 2021 at 11:41 Comment(0)
F
0

If you are using Kotlin and string resources, a simple solution is:

Create your string on strings.xml, using <b> </b> to bold the parts you want

<string name="my_message"> This is a very <b>important</b> message! </string>

On Kotlin code you must do like so

textView.setText(R.string.my_message)

And that is it!


Important note!

Using property syntax will not work:

textView.text = resources.getString(R.string.my_message)

Hope it helps!

Fluidextract answered 16/1, 2023 at 15:13 Comment(0)
F
0

In Kotlin,

Declare a sub string which you want to make bold:

val phone = "+45xxxxxx"

Wrap this string with desired color and a bold tag and save in another string:

val phoneText = "<font color=#757B7F><b>${phone}</b></font>"

Finally concatenate this sub string with your parent string:

val wholeString = requireActivity().resources.getString(R.string.loginwith)+" "+phoneText
Follow answered 1/2, 2023 at 12:53 Comment(1)
Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, can you edit your answer to include an explanation of what you're doing and why you believe it is the best approach?Bricebriceno
E
-1

Just add this in your tag

dangerouslySetInnerHTML={{__html: "<p>Your html text here.<p>"}}
Endive answered 14/7, 2021 at 5:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.