web-dev-qa-db-ger.com

so erstellen Sie einen bestimmten Text in TextView BOLD

Ich weiß nicht, wie ich einen bestimmten Text in TextView fett machen kann.

es ist so

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

Ich möchte, dass die Ausgabe so ist:

1111 neil

id und name sind Variablen, die ich aus der Datenbank abgerufen habe. Ich möchte, dass id fett dargestellt wird, aber nur die id-Datei, sodass name nicht betroffen ist.

171
Budi Darmawan

Erstellen Sie einfach Ihren String in HTML und legen Sie ihn fest:

String sourceString = "<b>" + id + "</b> " + name; 
mytextview.setText(Html.fromHtml(sourceString));
304
Raghav Sood

Während Sie Html.fromHtml () verwenden können, können Sie einen systemeigenen Ansatz verwenden, der SpannableStringBuilder ist. Dieses post kann hilfreich sein.

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);
306
wtsang02

Ich dachte, dass die gewählte Antwort kein zufriedenstellendes Ergebnis lieferte. Ich habe meine eigene Funktion geschrieben, die zwei Zeichenketten benötigt. Der vollständige Text und der Teil des Textes, den Sie fett hervorheben möchten.

Es gibt einen SpannableStringBuilder zurück, wobei 'textToBold' von 'text' fett gedruckt ist.

Ich finde die Möglichkeit, einen Teilstring fett zu machen, ohne ihn in Tags einzuwickeln.

    /**
     * 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;
  }
33
Eitan

Erstens: Sie brauchen sich nicht um die Verwendung des langsamen Leistungscodes aus der Antwort von Raghav Sood zu kümmern. 

Zweitens: Sie müssen keine Erweiterungsfunktion schreiben, die von w3bsharks Antwort bereitgestellt wird, wenn Sie Kotlin verwenden.

Finnaly: Alles was Sie tun müssen, ist die Kotlin Android-ktx-Bibliothek von Google zu verwenden:

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

Produziert: 1111 neil


UPDATE:

Ich denke, es kann jemandem helfen und zeigen, wie weit Sie hier gehen können. Dies sind weitere Anwendungsfälle.

  • Wenn Sie einen Text mit einigen Teilen in blau und kursiv anzeigen müssen:

    val myCustomizedString = SpannableStringBuilder()
        .color(blueColor, { append("A blue text ") })
        .append("showing that ")
        .italic{ append("it is painless") }
    
  • Wenn Sie einen Text fett und kursiv anzeigen müssen:

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

Kurz gesagt, bold, append, color und italic sind Erweiterungsfunktionen für SpannableStringBuilder. In der offiziellen Dokumentation finden Sie weitere Erweiterungsfunktionen, von denen Sie nach anderen Möglichkeiten denken können.

24

Wie wtsang02 sagte, ist die Verwendung von HTML ein teurer Aufwand. Verwenden Sie einfach die native Lösung. Wenn Sie die Zeichenfolge nicht ändern müssen, verwenden Sie einfach SpannableString, nicht 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);
16
Jadamec

Wenn Sie die Zeichenfolge aus XML verwenden möchten, können Sie Folgendes tun:

strings.xml

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

Code:

textView.setText(Html.fromHtml(getString(R.string.test)));
9

Hier ist die bessere Lösung, wenn Sie mehrere Texte fett formatieren möchten. Ich habe den Code von Eitan verbessert. Danke 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;
}
9
Krishna

Schließen Sie einfach den angegebenen Text wie folgt: <b>"your text here:"</b>

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

ergebnis: Hauptsitz: Mooresville, North Carolina, USA.

8
Rida

Basierend auf der Antwort von @ mladj0ni erhielt ich den folgenden Code zum Laufen. Das Problem war, dass, wenn Sie String.format verwenden, das HTML-Markup entfernt wird, sodass Sie die Klammer-Symbole in strings.xml escape

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);

Es ist einfacher als SpannableStringBuilder. Wenn Sie nur eine Zeichenfolge anzeigen, wird der Benutzer die zusätzliche Millisekunde zum Parsen nicht bemerken.

Siehe die Dokumentation hier .

6
Yusuf X

Ich kam hierher, um eine aktuellere Lösung bereitzustellen, da ich mit den vorhandenen Antworten nicht zufrieden war. Ich brauchte etwas, das für übersetzte Texte geeignet wäre, und hat nicht den Performance-Erfolg der Verwendung von Html.fromHtml(). Wenn Sie Kotlin verwenden, haben Sie hier eine Erweiterungsfunktion, mit der Sie einfach mehrere Teile Ihres Texts auf fett setzen können. Dies funktioniert genauso wie Markdown und kann bei Bedarf erweitert werden, um andere Markdown-Tags zu unterstützen.

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())
    }
}
3
w3bshark

Wenn Sie Kotlin verwenden, wird dies durch die Verwendung von core-ktx noch einfacher, da hierfür ein domain-specific-language (DSL bereitgestellt wird:

val string: SpannedString = buildSpannedString {
    bold {
        append("1111")
    }
    append("neil)     
}

Weitere Möglichkeiten sind:

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

Endlich können Sie einfach:

textView.text = string
3
Devansh Maurya

Machen Sie das erste Zeichen einer Zeichenfolge spannbar, während Sie nach Zeichen in der Liste/im Recycler suchen

r a vi und ajay

zuvor so hervorgehoben, aber ich wollte wie unten sein

ravi a nd ajayODERravi und a jay

dafür suchte ich nach der Wortlänge, wenn es gleich 1 ist, trennte ich die Hauptzeichenfolge in Wörter und berechnete die Startposition von Word, dann suchte ich das Wort, das mit char beginnt.

 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;
}
3
Sagar

Ich habe eine statische Methode zum Festlegen eines Teils des Textes Fett für TextView und EditText erstellt

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);

        }
    }

Ein weiterer mehr angepasster 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);
        }
    }
2
Xar E Ahmer

wtsang02 Antwort ist der beste Weg, um darüber nachzudenken, da Html.fromHtml ("") jetzt veraltet ist. Hier werde ich es nur ein wenig verbessern, wer das Problem hat, das erste Wort dynamisch fett zu machen, egal wie groß der Satz ist. 

Zuerst können wir eine Methode erstellen, um das erste Word zu erhalten:

 private String getFirstWord(String input){

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

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

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

    return input;
}

Nehmen wir an, Sie haben eine lange Saite wie folgt:

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

Und Sie möchten, dass Ihr Satz wie [email protected] / Ihr Freund sein soll! Alles, was Sie tun müssen, ist - das firstWord zu bekommen und die Länge davon zu erhalten, um das firstWord fett zu machen, so etwas diese:

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

Folgen Sie nun einfach den Schritten von wtsang02 :

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

Und das ist es! Jetzt sollten Sie in der Lage sein, ein Wort mit beliebiger Größe aus einem langen/kurzen Satz hervorzuheben. Hoffe es wird jemandem helfen, glückliche Kodierung :)

1
Junia Montana

Sie können die beiden Strings separat im Builder hinzufügen. Eine davon ist "spannedString", die andere ist eine reguläre. Auf diese Weise müssen Sie die Indizes nicht berechnen.

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)
public static Spanned getBoldString(String textNotBoldFirst, String textToBold, String textNotBoldLast) {
    String resultant = null;

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

    return Html.fromHtml(resultant);

}

Versuche dies. Es kann definitiv helfen 

1
Saad Bilal

wenn die Position von fettem Text festgelegt ist (z. B. wenn sich der Text am Anfang des TextView befindet), verwenden Sie zwei verschiedene TextView-Elemente mit demselben Hintergrund. Dann können Sie den textStyle des anderen textView fett formatieren.

Im Vergleich zu einer einzelnen Textansicht wird doppelt so viel Speicher benötigt wie mit einer einzelnen Textansicht. Die Geschwindigkeit wird jedoch erhöht.

0
neens

Dies ist die Kotlin-Erweiterungsfunktion, die ich dafür benutze

/**
 * 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)
}

Verwendungszweck:

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

.

text_view.setSubstringTypeface(
    Pair(
        "something bold",
        Typeface.BOLD
    ),
    Pair(
        "something italic",
        Typeface.ITALIC
    )
)
0
aaronmarino

Mit diesem Code können Sie einen Teil Ihres Textes fett setzen. Was auch immer zwischen den fetten HTML-Tags ist, macht es fett.

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;
        }
0
live-love

Hier ist meine Komplettlösung für dynamische String-Werte mit Fallprüfung.

/**
 * 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;
}

Z.B. completeString = "Ich bin BOLD"

CASE I Wenn *targetStringToFormat* = "bold" und *matchCase* = true 

gibt "Ich bin fett" zurück (seit Fett! = Fett)

CASE II Wenn *targetStringToFormat* = "bold" und *matchCase* = false

gibt zurück "Ich binFETT

Bewerben:

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

Hoffentlich hilft das!

0
sud007