วิธีสร้างส่วนหนึ่งของข้อความเป็นตัวหนาใน Android ที่รันไทม์


100

ListViewในใบสมัครของฉันมีองค์ประกอบหลายอย่างเช่นสตริงname, experience, date of joiningฯลฯ ฉันเพียงแค่ต้องการให้nameเป็นตัวหนา TextViewองค์ประกอบทั้งหมดสตริงจะอยู่ในที่เดียว

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>

รหัสของฉันเพื่อตั้งค่า TextView ของรายการ ListView:

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

คำตอบ:


232

สมมติว่าคุณมีที่เรียกว่าTextView etxจากนั้นคุณจะใช้รหัสต่อไปนี้:

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


2
สำหรับ Xamarin ให้ใช้แบบนี้var bss = new StyleSpan(Android.Graphics.TypefaceStyle.Bold);
Elisabeth

สำหรับ Xamarinetx.TextFormatted = sb;
Darius

28

จากคำตอบของ Imran Rana นี่เป็นวิธีการทั่วไปที่ใช้ซ้ำได้หากคุณต้องการใช้StyleSpans กับหลาย ๆ ตัวTextViewพร้อมรองรับหลายภาษา (โดยที่ดัชนีเป็นตัวแปร):

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

ใช้ในActivityลักษณะนี้:

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

ผลลัพธ์:

ยินดีต้อนรับสู่CompanyName


12

คำตอบที่ให้ไว้ที่นี่ถูกต้อง แต่ไม่สามารถเรียกแบบวนซ้ำได้เนื่องจากStyleSpanอ็อบเจ็กต์เป็นช่วงเดียวที่ต่อเนื่องกัน (ไม่ใช่สไตล์ที่สามารถใช้ได้กับหลายช่วง) การเรียกsetSpanหลาย ๆ ครั้งด้วยตัวหนาเดียวกันStyleSpanจะสร้างช่วงตัวหนาหนึ่งช่วงและเลื่อนไปมาในช่วงหลัก

ในกรณีของฉัน (การแสดงผลการค้นหา) ฉันจำเป็นต้องทำให้ทุกอินสแตนซ์ของคำค้นหาทั้งหมดแสดงเป็นตัวหนา นี่คือสิ่งที่ฉันทำ:

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

โปรดทราบว่าโค้ดด้านบนไม่ฉลาดพอที่จะข้ามการทำตัวหนาสองครั้งหากคำหลักหนึ่งเป็นสตริงย่อยของอีกคำหนึ่ง ตัวอย่างเช่นหากคุณค้นหาคำว่า "Fish fi"ภายใน"Fishes in the fisty Sea"จะทำให้"fish" เป็นตัวหนาหนึ่งครั้งแล้วตามด้วยส่วน"fi" สิ่งที่ดีก็คือแม้ว่าจะไม่มีประสิทธิภาพและไม่เป็นที่ต้องการสักหน่อย แต่ก็ไม่มีข้อเสียด้านภาพเนื่องจากผลลัพธ์ที่แสดงของคุณจะยังคงมีลักษณะเช่นนี้

ปลาในทะเลไฟ


เฮ้ผู้ชายได้โปรดดูstackoverflow.com/questions/59947482/…
Pemba Tamang

8

คุณสามารถทำได้โดยใช้ Kotlin และbuildSpannedStringฟังก์ชันส่วนขยายจากcore-ktx

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

5

หากคุณไม่ทราบความยาวของข้อความก่อนส่วนข้อความที่คุณต้องการทำให้เป็นตัวหนาหรือแม้แต่คุณไม่ทราบความยาวของข้อความที่จะเป็นตัวหนาคุณสามารถใช้แท็ก HTML ดังต่อไปนี้:

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

0

การขยายคำตอบของ Frieder เพื่อรองรับความรู้สึกไม่ไวต่อตัวพิมพ์และตัวกำกับเสียง

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

0

หากคุณกำลังใช้คำอธิบายประกอบ @ srings / your_string ให้เข้าถึงไฟล์ strings.xml และใช้<b></b>แท็กในส่วนของข้อความที่คุณต้องการ

ตัวอย่าง:

    <string><b>Bold Text</b><i>italic</i>Normal Text</string>

-1

ฉันแนะนำให้ใช้ไฟล์ strings.xml กับ CDATA

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

จากนั้นในไฟล์ java:

TextView myTextView = (TextView) this.findViewById(R.id.myTextView);
myTextView.setText(Html.fromHtml( getResources().getString(R.string.mystring) ));
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.