Bagaimana cara membuat bagian dari teks Bold di android saat runtime?

101

Sebuah ListViewdi aplikasi saya memiliki banyak unsur string seperti name, experience, date of joining, dll saya hanya ingin membuat nameberani. Semua elemen string akan menjadi satu TextView.

XML saya:

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

Kode saya untuk mengatur TextView dari item ListView:

holder.text.setText(name + "\n" + expirience + " " + dateOfJoininf);
Lalat
sumber

Jawaban:

233

Katakanlah Anda memiliki TextViewyang disebut etx. Anda kemudian akan menggunakan kode berikut:

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
sumber
2
Untuk Xamarin, gunakan seperti inivar bss = new StyleSpan(Android.Graphics.TypefaceStyle.Bold);
Elisabeth
Untuk Xamarin,etx.TextFormatted = sb;
Darius
28

Berdasarkan jawaban Imran Rana, berikut adalah metode umum yang dapat digunakan kembali jika Anda perlu menerapkan StyleSpans ke beberapa TextView, dengan dukungan untuk banyak bahasa (di mana indeks adalah variabel):

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

Gunakan Activityseperti ini:

@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>

Hasil:

Selamat datang di CompanyName

friederbluemle.dll
sumber
12

Jawaban yang diberikan di sini benar, tetapi tidak dapat dipanggil dalam satu lingkaran karena StyleSpanobjeknya adalah satu rentang bersebelahan (bukan gaya yang dapat diterapkan ke beberapa bentang). Memanggil setSpanbeberapa kali dengan huruf tebal yang sama StyleSpanakan membuat satu bentang tebal dan hanya memindahkannya dalam bentang induk.

Dalam kasus saya (menampilkan hasil pencarian), saya perlu membuat semua contoh dari semua kata kunci pencarian tampak tebal. Inilah yang saya lakukan:

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

Perlu diingat bahwa kode di atas tidak cukup pintar untuk melewati penebalan ganda jika satu kata kunci adalah substring dari kata kunci lainnya. Misalnya, jika Anda mencari "Fish fi" di dalam "Fishes in the fisty Sea", ini akan membuat "fish" menjadi tebal sekali dan kemudian bagian "fi" . Hal baiknya adalah meskipun tidak efisien dan sedikit tidak diinginkan, itu tidak akan memiliki kekurangan visual karena hasil yang Anda tampilkan akan tetap terlihat seperti

Ikan es di fi Laut sty

copolii
sumber
hai man, bisakah Anda melihat stackoverflow.com/questions/59947482/…
Pemba Tamang
8

Anda dapat melakukannya menggunakan Kotlin dan buildSpannedStringfungsi ekstensi daricore-ktx

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

Jika Anda tidak tahu persis panjang teks sebelum bagian teks yang ingin Anda buat Bold, atau bahkan Anda tidak tahu panjang teks yang akan ditebalkan, Anda dapat dengan mudah menggunakan tag HTML seperti berikut:

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

Memperluas jawaban Frieder untuk kasus dukungan dan ketidaksensitifan diakritik.

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
sumber
0

Jika Anda menggunakan anotasi @ srings / your_string, akses file strings.xml dan gunakan <b></b>tag di bagian teks yang Anda inginkan.

Contoh:

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

Saya merekomendasikan untuk menggunakan file strings.xml dengan CDATA

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

Kemudian di file java:

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