developer tip

런타임에 Android에서 텍스트의 일부를 굵게 만드는 방법은 무엇입니까?

optionbox 2020. 10. 11. 10:27
반응형

런타임에 Android에서 텍스트의 일부를 굵게 만드는 방법은 무엇입니까?


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>

ListView 항목의 TextView를 설정하는 내 코드 :

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

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


Imran Rana의 답변 에 따라 여러 언어 (인덱스가 변수 인 경우)를 지원 StyleSpan하여 여러 TextViews에 s를 적용해야하는 경우 일반적인 재사용 가능한 방법이 있습니다 .

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에 오신 것을 환영합니다.


여기에 제공된 답변은 정확하지만 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;
}

Keep in mind that the code above isn't smart enough to skip double-bolding if one keyword is a substring of the other. For example, if you search for "Fish fi" inside "Fishes in the fisty Sea" it will make the "fish" bold once and then the "fi" portion. The good thing is that while inefficient and a bit undesirable, it won't have a visual drawback as your displayed result will still look like

Fishes in the fisty Sea


if you don't know exactly the length of the text before the text portion that you want to make Bold, or even you don't know the length of the text to be Bold, you can easily use HTML tags like the following:

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

Extending frieder's answer to support case and diacritics insensitivity.

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

I recommend to use strings.xml file with CDATA

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

Then in the java file :

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

참고URL : https://stackoverflow.com/questions/10979821/how-to-make-part-of-the-text-bold-in-android-at-runtime

반응형