Android: TextView.setText () kullanarak bir dizenin bir bölümünü renklendirme?


88

.SetText ("") yöntemi aracılığıyla bir TextView görünümünün metnini değiştirirken, aynı zamanda metnin bir bölümünü renklendirirken (veya kalın, italik, şeffaf vb.) Diğerini değil. Örneğin:

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

Yukarıdaki kodun yanlış olduğunu biliyorum, ancak neye ulaşmak istediğimi göstermeye yardımcı oluyor. Bunu nasıl yaparım?



TextView'de uzun bir metin varsa, daha verimli bir yol var
Mingfei


Yanıtlar:


203

Açıklıkları kullanın .

Misal:

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
Kelimelerimde kaç karakter olduğu hakkında hiçbir fikrim olmadığı için çoklu dil ile çalışmadığı için android'in burada sunduğu çözümü gerçekten sevmiyorum. Şu anda, hepsini bir TextView'a ekleyebileceğim ve daha sonra bir araya getirebileceğim birden fazla
aralığa

1
Metni kalınlaştırmak için aralık diyen yorum, metin rengini yapmak için açıklık mı demeli?
Ryhan

9
@philipp, sorununuz kelimenizde kaç karakter ise, String veya StringBuilder veya her neyse, length () yöntemini kullanın
Ahmed Adel İsmail

1
TextView'da uzun bir metin varsa, işte daha etkili bir yol
Mingfei

Cevabı okurken başlangıçta bunu kaçırdım, ancak bitiş dizininizin dizedeki bitiş dizinini +1 olması gerekiyor (yani, ilk dört harfi yaymak için [başlangıç, bitiş] 'i [0, 4] değil [0, 3])
tir38

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

2
Bu, orijinal soruna işaretli cevaptan çok daha hoş bir çözümdür.
BSnapZ

1
Satır sonlarınız varsa \ n, bu satır sonlarını göstermez.
live-love

9
Hayır, daha hoş değil, söz konusu olan renklendirme özelliği yok ama HTML () 'den YAVAŞ yöntemi
Viktor Yakunin

1
Yani kullanmak <font color="#FFAADD>text</font>işe yaramaz mı?
milosmns

25

Umarım bu size yardımcı olur (çoklu dil ile çalışır).

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

Ve java kodunuzda şunları yapabilirsiniz:

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

Bu şekilde, yalnızca "Test" bölümü renkli (ve kalın) olacaktır.


3
En iyi cevap. Bu, uluslararasılaştırılmış dizeler için mükemmel çalışır. Ayrıca, renkli metninizin dize kaynağınızın ortasında olması avantajına da sahiptir.
jt-gilkeson

Daha fazla açıklama için, buradaki HTML işaretlemesiyle Stil verme bölümüne bakın .
Elisabeth

17

İşte bir kelimenin geçtiği tüm yerleri arayacak (büyük / küçük harfe duyarsız) ve onları kırmızıya boyayacak bir örnek:

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

Adınızı seviyorum: P Belirli bir kelimenin arka planını yeni BackgroundColorSpan (Color.parseColor ("# BFFFC6")) ile değiştirebilir miyim?
Ajay Pandya

9

Kotlin kullanıyorsanız android-ktx kitaplığını kullanarak aşağıdakileri yapabilirsiniz.

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

titleTextField.text = title

boldBir uzantı fonksiyonudur SpannableStringBuilder. Sen belgelerine görebilirsiniz burada kullanabileceğiniz operasyonların listesi için.

Başka bir örnek:

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

Çözülmüş greenbir RGB rengi nerede .

Gömülü DSL gibi bir şeye sahip olmanız için aralıkları iç içe yerleştirmek bile mümkündür:

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

build.gradleÇalışması için uygulama modülü seviyenizde aşağıdakilere ihtiyacınız olacak :

repositories {
    google()
}

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

Ayrıca hangi rengi koyarsam koyayım aynı mor rengi gösteriyor. val spannableStringBuilder = SpannableStringBuilder() spannableStringBuilder.bold { underline { color(R.color.test_color) { append(underlinedText) } } }
Abhishek Saxena

8

SpannableBir metnin belirli kısımlarını belirli yönleri vermek için a kullanabilirsiniz . İstersen bir örnek arayabilirim.

Ah, doğru burada andan itibaren 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);

Çok dilli metin için başlangıç ​​ve bitiş aralığını nasıl yapılandırabiliriz?
Mübarek

Bir fikir, vurgulamanız ve ayrı bir dize kaynağı olarak çıkarmanız gereken kelimeyi tanımlamak olabilir. İfadeyi çevirirken, ayrı kelimeyi güncellemeyi de düşünmeniz gerekecektir, böylece span'ı stringOf'un indexOf'una ve uzunluğunun dizgesinin başlangıç ​​ve bitiş dizinlerini dinamik olarak ayarlayacak şekilde ayarlayacak şekilde ayarladığınızda.
Ionut Negru

4

HTML kullanmak istiyorsanız, kullanmanız gerekir TextView.setText(Html.fromHtml(String htmlString))

Bunu sık sık / tekrar tekrar yapmak istiyorsanız, yazdığım bir sınıfa ( SpannableBuilder ) bir göz atabilirsinizHtml.fromHtml() , çünkü çok verimli değildir (içinde büyük bir xml ayrıştırma makinesi kullanıyor). Bu blog gönderisinde açıklanmıştır .


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

Kullanma

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

textView.setText(spannable);

görüntü açıklamasını buraya girin


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

veya bu kodu kullanın:

    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

Kullanmayı severim SpannableStringBuilderDize uzunluklarını hesaplayarak setSpan'ı çağırmak yerine farklı aralıkları tek tek ekleyerek

as: (Kotlin kodu)

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

Sonuç


2

İki veya daha fazla Aralığı birleştirebilirsiniz. Bu şekilde, uzunluk değerini kullanarak dinamik metni renklendirmek daha kolaydır.

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

Bu kodu kullanmak faydalı

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.