Wie mache ich einen Teil des Textes in Android zur Laufzeit fett?

96

Ein ListViewin meiner Anwendung hat viele Textelemente , wie name, experience, date of joiningusw. Ich möchte nur machen namefett. Alle Zeichenfolgenelemente werden in einem einzigen Element zusammengefasst TextView.

mein XML:

<ImageView
    android:id="@+id/logo"
    android:layout_width="55dp"
    android:layout_height="55dp"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:layout_marginTop="15dp" >
</ImageView>

<TextView
    android:id="@+id/label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@id/logo"
    android:padding="5dp"
    android:textSize="12dp" >
</TextView>

Mein Code zum Festlegen der Textansicht des ListView-Elements:

holder.text.setText(name + "\n" + expirience + " " + dateOfJoininf);
Stubenfliege
quelle

Antworten:

229

Angenommen, Sie haben einen TextViewAnruf etx. Sie würden dann den folgenden Code verwenden:

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

Imran Rana
quelle
2
Für Xamarin, Verwendung wie diesevar bss = new StyleSpan(Android.Graphics.TypefaceStyle.Bold);
Elisabeth
Für Xamarinetx.TextFormatted = sb;
Darius
27

Basierend auf der Antwort von Imran Rana ist hier eine generische, wiederverwendbare Methode, wenn Sie StyleSpans auf mehrere TextViews anwenden müssen , mit Unterstützung für mehrere Sprachen (wobei Indizes variabel sind):

void setTextWithSpan(TextView textView, String text, String spanText, StyleSpan style) {
    SpannableStringBuilder sb = new SpannableStringBuilder(text);
    int start = text.indexOf(spanText);
    int end = start + spanText.length();
    sb.setSpan(style, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
    textView.setText(sb);
}

Verwenden Sie es Activityso:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...

    StyleSpan boldStyle = new StyleSpan(Typeface.BOLD);
    setTextWithSpan((TextView) findViewById(R.id.welcome_text),
        getString(R.string.welcome_text),
        getString(R.string.welcome_text_bold),
        boldStyle);

    // ...
}

strings.xml

<string name="welcome_text">Welcome to CompanyName</string>
<string name="welcome_text_bold">CompanyName</string>

Ergebnis:

Willkommen bei CompanyName

friederbluemle
quelle
12

Die hier angegebenen Antworten sind korrekt, können jedoch nicht in einer Schleife aufgerufen werden, da das StyleSpanObjekt ein einzelner zusammenhängender Bereich ist (kein Stil, der auf mehrere Bereiche angewendet werden kann). Wenn Sie setSpanmehrmals mit demselben Fettdruck StyleSpanaufrufen, wird ein Fettdruckbereich erstellt und nur im übergeordneten Bereich verschoben.

In meinem Fall (Anzeigen von Suchergebnissen) musste ich dafür sorgen, dass alle Instanzen aller Suchschlüsselwörter fett angezeigt werden. Das habe ich getan:

private static SpannableStringBuilder emboldenKeywords(final String text,
                                                       final String[] searchKeywords) {
    // searching in the lower case text to make sure we catch all cases
    final String loweredMasterText = text.toLowerCase(Locale.ENGLISH);
    final SpannableStringBuilder span = new SpannableStringBuilder(text);

    // for each keyword
    for (final String keyword : searchKeywords) {
        // lower the keyword to catch both lower and upper case chars
        final String loweredKeyword = keyword.toLowerCase(Locale.ENGLISH);

        // start at the beginning of the master text
        int offset = 0;
        int start;
        final int len = keyword.length(); // let's calculate this outside the 'while'

        while ((start = loweredMasterText.indexOf(loweredKeyword, offset)) >= 0) {
            // make it bold
            span.setSpan(new StyleSpan(Typeface.BOLD), start, start+len, SPAN_INCLUSIVE_INCLUSIVE);
            // move your offset pointer 
            offset = start + len;
        }
    }

    // put it in your TextView and smoke it!
    return span;
}

Beachten Sie, dass der obige Code nicht intelligent genug ist, um doppelte Fettdrucke zu überspringen, wenn ein Schlüsselwort eine Teilzeichenfolge des anderen ist. Zum Beispiel, wenn Sie nach "Fish fi" suchen in "Fische im fistigen Meer" suchen , wird der "Fisch" einmal fett und dann der Teil "fi" fett gedruckt . Das Gute ist, dass es zwar ineffizient und etwas unerwünscht ist, aber keinen visuellen Nachteil hat, da Ihr angezeigtes Ergebnis immer noch so aussieht

Fische es in der fi sty Sea

copolii
quelle
Hey Mann, können Sie bitte diese stackoverflow.com/questions/59947482/…
Pemba Tamang
6

Sie können dies mit Kotlin und der buildSpannedStringErweiterungsfunktion von tuncore-ktx

 holder.textView.text = buildSpannedString {
        bold { append("$name\n") }
        append("$experience $dateOfJoining")
 }
Dmitrii Leonov
quelle
5

Wenn Sie die Länge des Textes vor dem Textabschnitt, den Sie fett machen möchten, nicht genau kennen oder auch nicht wissen, wie lang der Text fett sein soll, können Sie problemlos HTML-Tags wie die folgenden verwenden:

yourTextView.setText(Html.fromHtml("text before " + "<font><b>" + "text to be Bold" + "</b></font>" + " text after"));
Muhammed Refaat
quelle
0

Erweiterung der Antwort von Frieder auf die Unempfindlichkeit gegenüber Groß- und Kleinschreibung.

public static String stripDiacritics(String s) {
        s = Normalizer.normalize(s, Normalizer.Form.NFD);
        s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");
        return s;
}

public static void setTextWithSpan(TextView textView, String text, String spanText, StyleSpan style, boolean caseDiacriticsInsensitive) {
        SpannableStringBuilder sb = new SpannableStringBuilder(text);
        int start;
        if (caseDiacriticsInsensitive) {
            start = stripDiacritics(text).toLowerCase(Locale.US).indexOf(stripDiacritics(spanText).toLowerCase(Locale.US));
        } else {
            start = text.indexOf(spanText);
        }
        int end = start + spanText.length();
        if (start > -1)
            sb.setSpan(style, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        textView.setText(sb);
    }
luky
quelle
0

Wenn Sie die Annotation @ srings / your_string verwenden, greifen Sie auf die Datei strings.xml zu und verwenden Sie das <b></b>Tag in dem gewünschten Textteil.

Beispiel:

    <string><b>Bold Text</b><i>italic</i>Normal Text</string>
Isaias Carvalho
quelle
-1

Ich empfehle, die Datei strings.xml mit CDATA zu verwenden

<string name="mystring"><![CDATA[ <b>Hello</b> <i>World</i> ]]></string>

Dann in der Java-Datei:

TextView myTextView = (TextView) this.findViewById(R.id.myTextView);
myTextView.setText(Html.fromHtml( getResources().getString(R.string.mystring) ));
sonique
quelle