Android : TextView.setText ()를 사용하여 문자열의 일부를 색칠합니까?


86

.setText ( "") 메서드를 통해 TextView보기의 텍스트를 변경하는 동시에 텍스트의 일부를 채색 (또는 굵게, 기울임 꼴, 투명 등)하고 나머지는 변경하지 않으려 고합니다. 예를 들면 :

title.setText("Your big island <b>ADVENTURE!</b>";

위의 코드가 올바르지 않다는 것을 알고 있지만 달성하고 싶은 것을 설명하는 데 도움이됩니다. 어떻게해야합니까?



텍스트 뷰에서 긴 텍스트가있는 경우,이 보다 효율적인 방법
Mingfei


Spans를 사용하는 Kotlin의 솔루션 stackoverflow.com/a/59510004/11166067
Dmitrii Leonov

답변:


201

스팬을 사용 합니다.

예:

final SpannableStringBuilder sb = new SpannableStringBuilder("your text here");

// Span to set text color to some RGB value
final ForegroundColorSpan fcs = new ForegroundColorSpan(Color.rgb(158, 158, 158)); 

// Span to make text bold
final StyleSpan bss = new StyleSpan(android.graphics.Typeface.BOLD); 

// Set the text color for first 4 characters
sb.setSpan(fcs, 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE); 

// make them also bold
sb.setSpan(bss, 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE); 

yourTextView.setText(sb);

11
나는 내 말에 얼마나 많은 문자가 있는지 알지 못하기 때문에 다중 언어로 작동하지 않기 때문에 여기에서 안드로이드가 제공하는 솔루션이 마음에 들지 않습니다. 저는 현재 TextView에 모두 첨부 할 수있는 여러 스팬을 가질 수있는 솔루션을 찾고 있습니다. 그런 다음 그것들을 합칠 수 있습니다.
philipp

1
텍스트를 굵게 만들려면 span이라는 주석, 텍스트 색상을 만들려면 span이라고해야합니까?
Ryhan

9
@philipp 문제가 단어의 문자 수인 경우 String 또는 StringBuilder 등에서 length () 메서드를 사용합니다.
Ahmed Adel Ismail

1
텍스트 뷰에서 긴 텍스트가있는 경우, 여기 보다 효율적인 방법
Mingfei

처음에는 답을 읽을 때 이것을 놓쳤지만 끝 색인은 문자열의 끝 색인을 +1해야합니다 (즉, 처음 네 글자를 포함하려면 [시작, 끝]을 [0이 아닌 [0, 4]로 설정해야합니다. 3])
tir38

46
title.setText(Html.fromHtml("Your big island <b>ADVENTURE!</b>")); 

2
이것은 표시된 답변보다 원래 문제에 대한 훨씬 더 좋은 해결책입니다.
BSnapZ

1
줄 바꿈이있는 경우 \ n, 줄 바꿈이 표시되지 않습니다.
live-love

8
아니, 더 착색 기능, 질문하지만, SLOW 방법 fromHTML ()에서 언급이 없다가 아니라 좋네요
빅토르 Yakunin

1
그래서 사용 <font color="#FFAADD>text</font>이 작동하지 않습니까?
milosmns

25

이 정보가 도움이 되었기를 바랍니다 (다국어 지원).

<string name="test_string" ><![CDATA[<font color="%1$s"><b>Test/b></font>]]> String</string>

그리고 자바 코드에서 다음을 수행 할 수 있습니다.

int color = context.getResources().getColor(android.R.color.holo_blue_light);
String string = context.getString(R.string.test_string, color);
textView.setText(Html.fromHtml(string));

이렇게하면 "테스트"부분 만 색상이 지정되고 굵게 표시됩니다.


3
베스트 답변. 이것은 국제화 된 문자열에 완벽하게 작동합니다. 또한 문자열 리소스 중간에 컬러 텍스트를 넣을 수 있다는 장점이 있습니다.
jt-gilkeson

자세한 설명은 여기 에서 HTML 마크 업으로 스타일 지정 섹션을 참조 하십시오 .
Elisabeth

17

다음은 단어의 모든 발생 (대소 문자 구분 안 함)을 찾아 빨간색으로 표시하는 예입니다.

String notes = "aaa AAA xAaax abc aaA xxx";
SpannableStringBuilder sb = new SpannableStringBuilder(notes);
Pattern p = Pattern.compile("aaa", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(notes);
while (m.find()){
    //String word = m.group();
    //String word1 = notes.substring(m.start(), m.end());

    sb.setSpan(new ForegroundColorSpan(Color.rgb(255, 0, 0)), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
editText.setText(sb);

나는 당신의 이름을 사랑합니다 : P 새로운 BackgroundColorSpan (Color.parseColor ( "# BFFFC6"))로 특정 단어의 배경을 변경할 수 있습니까?
아제 디야

8

a Spannable를 사용하여 텍스트의 특정 부분에 특정 측면을 제공 할 수 있습니다 . 원하시면 예를 찾아 볼 수 있습니다.

아, 바로 여기에서 stackoverflow .

TextView TV = (TextView)findViewById(R.id.mytextview01); 
Spannable WordtoSpan = new SpannableString("I know just how to whisper, And I know just how to cry,I know just where to find the answers");        
WordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TV.setText(WordtoSpan);

다국어 텍스트의 시작 및 끝 범위를 어떻게 구성 할 수 있습니까?
무바라크

8

Kotlin을 사용하는 경우 android-ktx 라이브러리를 사용하여 다음을 수행 할 수 있습니다.

val title = SpannableStringBuilder()
        .append("Your big island ")
        .bold { append("ADVENTURE") } 

titleTextField.text = title

bold확장 기능입니다 SpannableStringBuilder. 사용할 수있는 작업 목록은 여기 에서 설명서를 참조하십시오 .

또 다른 예:

val ssb = SpannableStringBuilder()
            .color(green) { append("Green text ") }
            .append("Normal text ")
            .scale(0.5F) { append("Text at half size ") }
            .backgroundColor(green) { append("Background green") }

green해결 된 RGB 색상은 어디에 있습니까 ?

스팬을 중첩하여 임베디드 DSL과 같은 결과를 얻을 수도 있습니다.

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

build.gradle작동하려면 앱 모듈 수준에서 다음이 필요합니다 .

repositories {
    google()
}

dependencies {
    implementation 'androidx.core:core-ktx:0.3'
}

또 어떤 색을 넣어도 보라색이 똑같아요. val spannableStringBuilder = SpannableStringBuilder() spannableStringBuilder.bold { underline { color(R.color.test_color) { append(underlinedText) } } }
Abhishek Saxena

4

HTML을 사용하려면 다음을 사용해야합니다. TextView.setText(Html.fromHtml(String htmlString))

자주 / 반복적으로 수행하고 싶다면 내가 작성한 클래스 ( SpannableBuilder )를 볼 수 있습니다. Html.fromHtml()별로 효율적이지 않습니다 (내부에서 큰 xml 구문 분석 기계를 사용하고 있음). 이 블로그 게시물에 설명되어 있습니다.


4
public static void setColorForPath(Spannable spannable, String[] paths, int color) {
    for (int i = 0; i < paths.length; i++) {
        int indexOfPath = spannable.toString().indexOf(paths[i]);
        if (indexOfPath == -1) {
            continue;
        }
        spannable.setSpan(new ForegroundColorSpan(color), indexOfPath,
                indexOfPath + paths[i].length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}

사용

Spannable spannable = new SpannableString("Your big island ADVENTURE");
Utils.setColorForPath(spannable, new String[] { "big", "ADVENTURE" }, Color.BLUE);

textView.setText(spannable);

여기에 이미지 설명 입력


3

            String str1 = "If I forget my promise to ";
            String penalty = "Eat breakfast every morning,";
            String str2 = " then I ";
            String promise = "lose my favorite toy";
           

            String strb = "<u><b><font color='#081137'>"+ penalty +",</font></b></u>";
            String strc = "<u><b><font color='#081137'>"+ promise + "</font></b></u>";
            String strd = str1 +strb+ str2 + strc;
           tv_notification.setText(Html.fromHtml(strd));

또는 다음 코드를 사용하십시오.

    SpannableStringBuilder builder = new SpannableStringBuilder();
            SpannableString text1 = new SpannableString(str1);
            text1.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.silver)), 0, str1.length() - 1, 0);
            builder.append(text1);

            SpannableString text2 = new SpannableString(penalty);
            text2.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.midnight)), 0, penalty.length(), 0);
            text2.setSpan(new UnderlineSpan(), 0, penalty.length(), 0);
            builder.append(text2);

            SpannableString text3 = new SpannableString(str2);
            text3.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.silver)),0, str2.length(), 0);
            builder.append(text3);


            SpannableString text4 = new SpannableString(promise);
            text4.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.midnight)), 0, promise.length(), 0);
            text4.setSpan(new UnderlineSpan(),0, promise.length(), 0);
            builder.append(text4);

          tv_notification.setText(builder);


3

SpannableStringBuilder문자열 길이를 계산하여 setSpan을 호출하는 것보다 하나씩 다른 범위를 추가하여 사용 하고 싶습니다.

as : (Kotlin 코드)

val amountSpannableString = SpannableString("₹$amount").apply {
  // text color
  setSpan(ForegroundColorSpan("#FD0025".parseColor()), 0, length, 0)
  // text size
  setSpan(AbsoluteSizeSpan(AMOUNT_SIZE_IN_SP.spToPx(context)), 0, length, 0)
  // font medium
  setSpan(TypefaceSpan(context.getString(R.string.font_roboto_medium)), 0, length, 0)
}

val spannable: Spannable = SpannableStringBuilder().apply {
  // append the different spans one by one
  // rather than calling setSpan by calculating the string lengths
  append(TEXT_BEFORE_AMOUNT)
  append(amountSpannableString)
  append(TEXT_AFTER_AMOUNT)
}

결과


2

두 개 이상의 Span을 연결할 수 있습니다. 이렇게하면 길이 값을 사용하여 동적 텍스트에 색상을 지정하는 것이 더 쉽습니다.

SpannableStringBuilder span1 = new SpannableStringBuilder("Android");
ForegroundColorSpan color1=new ForegroundColorSpan(getResources().getColor(R.color.colorPrimary));
span1.setSpan(color1, 0, span1.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);

SpannableStringBuilder span2 = new SpannableStringBuilder("Love");
ForegroundColorSpan color2=new ForegroundColorSpan(getResources().getColor(R.color.colorSecondary));
span2.setSpan(color2, 0, span2.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);

Spanned concatenated=(Spanned) TextUtils.concat(span1," => ",span2);

SpannableStringBuilder result = new SpannableStringBuilder(concatenated);

TextView tv = (TextView) rootView.findViewById(R.id.my_texview);
tv.setText(result, TextView.BufferType.SPANNABLE);

2

이 코드를 사용하면 도움이됩니다.

TextView txtTest = (TextView) findViewById(R.id.txtTest);
txtTest.setText(Html.fromHtml("This is <font color="#ff4343">Red</font> Color!"));

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.