Pojedynczy TextView z wieloma kolorowymi tekstami

167

Jak mówi tytuł, chcę wiedzieć, czy można uzyskać dwa różne kolorowe znaki w jednym elemencie Textview.

Andro Selva
źródło
1
Nie jest to duplikat, ponieważ pytający prosi konkretnie o kolor.
Iqbal
Myślę, że jest do tego niezła biblioteka: blog.stylingandroid.com/rialto-downloadable-fonts github.com/StylingAndroid/Rialto
programista Androida
napisałem też bibliotekę, która zachowuje się podobnie do tego: github.com/ha-yi/MultiColorTextView
Hayi Nukman

Odpowiedzi:

328

tak, jeśli sformatujesz właściwość Stringwith html, font-colorprzekaż ją do metodyHtml.fromHtml(your text here)

String text = "<font color=#cc0029>First Color</font> <font color=#ffcc00>Second Color</font>";
yourtextview.setText(Html.fromHtml(text));
2red13
źródło
Dzięki również pomocny dla mnie. +1
Hardik Joshi
10
Nie zapomnij uciec przed wejściem użytkownika za pomocą Html.escapeHtml(str).
kelunik
1
Dodano na poziomie API 1
2red13
3
Tylko ostrzeżenie. Miałem problem, gdy potrzebowałem, aby mój tekst był pisany wielkimi literami. Używałem android: textAllCaps = "true" w XML i jednocześnie zawartość HTML była zapisana wielkimi literami. To nie działało. Usunąłem atrybut XML i teraz działa dobrze. Uważaj, bo jeśli użyjesz setAllCaps () w kodzie, pojawi się ten sam problem.
joao2fast4u
5
Html.fromHtml(String)jest teraz przestarzała, zamiast tego użyj Html.fromHtml(String, Html.FROM_HTML_MODE_LEGACY). Więcej informacji można znaleźć tutaj.
JediBurrell
165

Możesz drukować wiersze w wielu kolorach bez kodu HTML jako:

TextView textView = (TextView) findViewById(R.id.mytextview01);
Spannable word = new SpannableString("Your message");        

word.setSpan(new ForegroundColorSpan(Color.BLUE), 0, word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

textView.setText(word);
Spannable wordTwo = new SpannableString("Your new message");        

wordTwo.setSpan(new ForegroundColorSpan(Color.RED), 0, wordTwo.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.append(wordTwo);
Swapnil Kotwal
źródło
świetnie, dzięki, też mogę zrobić BackgroundColorSpan. w twoim przykładzie jest mała literówka, WordToSpan i WordtoSpan, zwróć uwagę na przypadek To
steveh.
jak przejść do testowania jednostkowego widoku tekstu, aby upewnić się, że tekst kończy się na Color.RED stackoverflow.com/questions/26611533/ ...
sudocoder
1
Nie działa dla mnie, otrzymuję `java.lang.StringIndexOutOfBoundsException: length = 3; index = 12`
Muhammad Babar
1
StringIndexOutOfBoundsException sam w sobie wyjaśnia. Uzyskujesz dostęp do ciągu poza jego długością.
Swapnil Kotwal
1
Moje ciągi nie zostały naprawione, więc ciągi byłyby generowane w czasie wykonywania aplikacji. Wypróbowałem prawie wszystkie odpowiedzi na to pytanie. Ale tylko to rozwiązanie działało u mnie.
Md. Sabbir Ahmed
33

Możesz użyć, Spannableaby zastosować efekty do TextView:

Oto mój przykład na kolorowanie tylko pierwszej części TextViewtekstu (pozwalając na dynamiczne ustawianie koloru, a nie na sztywne kodowanie go w łańcuchu, jak w przykładzie HTML!)

    mTextView.setText("Red text is here", BufferType.SPANNABLE);
    Spannable span = (Spannable) mTextView.getText();
    span.setSpan(new ForegroundColorSpan(0xFFFF0000), 0, "Red".length(),
             Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

W tym przykładzie możesz zamienić 0xFFFF0000 na getResources().getColor(R.color.red)

Graeme
źródło
1
Jeśli potrzebujesz tej wielkiej litery, po prostu użyj ciągów znaków w górę ().
Graeme
33

Zrobiłem w ten sposób:

Sprawdź referencje

Zestaw kolorów na tekst przez przepuszczenie String i kolor :

private String getColoredSpanned(String text, String color) {
    String input = "<font color=" + color + ">" + text + "</font>";
    return input;
}

Ustaw tekst na TextView / Button / EditText itp., Wywołując poniższy kod:

Widok tekstu:

TextView txtView = (TextView)findViewById(R.id.txtView);

Zdobądź kolorowy sznur:

String name = getColoredSpanned("Hiren", "#800000");
String surName = getColoredSpanned("Patel","#000080");

Ustaw tekst w TextView dwóch ciągów o różnych kolorach:

txtView.setText(Html.fromHtml(name+" "+surName));

Gotowe

Hiren Patel
źródło
1
nyc jeden, ale HTml.fromHtml jest przestarzały z API 24
Anuraj R
Możesz zamienić połączenia na Html.fromHtml("...")połączenia doHtml.fromHtml("...", FROM_HTML_MODE_LEGACY)
stkent
31

Użyj SpannableStringBuilder

SpannableStringBuilder builder = new SpannableStringBuilder();

SpannableString str1= new SpannableString("Text1");
str1.setSpan(new ForegroundColorSpan(Color.RED), 0, str1.length(), 0);
builder.append(str1);

SpannableString str2= new SpannableString(appMode.toString());
str2.setSpan(new ForegroundColorSpan(Color.GREEN), 0, str2.length(), 0);
builder.append(str2);

TextView tv = (TextView) view.findViewById(android.R.id.text1);
tv.setText( builder, TextView.BufferType.SPANNABLE);
Biswajit Karmakar
źródło
8

Hej, zrobiłem to, spróbujcie

TextView textView=(TextView)findViewById(R.id.yourTextView);//init

//here I am appending two string into my textView with two diff colors.
//I have done from fragment so I used here getActivity(), 
//If you are trying it from Activity then pass className.this or this; 

textView.append(TextViewUtils.getColoredString(getString(R.string.preString),ContextCompat.getColor(getActivity(),R.color.firstColor)));
textView.append(TextViewUtils.getColoredString(getString(R.string.postString),ContextCompat.getColor(getActivity(),R.color.secondColor)));

Wewnątrz klasy TextViewUtils dodaj tę metodę

 /***
 *
 * @param mString this will setup to your textView
 * @param colorId  text will fill with this color.
 * @return string with color, it will append to textView.
 */
public static Spannable getColoredString(String mString, int colorId) {
    Spannable spannable = new SpannableString(mString);
    spannable.setSpan(new ForegroundColorSpan(colorId), 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    Log.d(TAG,spannable.toString());
    return spannable;
}
Abdul Rizwan
źródło
Właśnie zaktualizowałem, sprawdź to raz, działa dla mnie.
Abdul Rizwan
Myabe używasz Html.fromHtml do użycia tego ciągu?
Sergey Shustikov
wewnątrz pliku string.xml Utworzyłem zmienną i ustawiłem ją, teraz działa dla mnie. Robię to, czy możesz podać tutaj swój ciąg.
Abdul Rizwan,
5

Lepiej jest użyć ciągu w pliku ciągów, jako takiego:

    <string name="some_text">
<![CDATA[
normal color <font color=\'#06a7eb\'>special color</font>]]>
    </string>

Stosowanie:

textView.text=HtmlCompat.fromHtml(getString(R.string.some_text), HtmlCompat.FROM_HTML_MODE_LEGACY)
programista Androida
źródło
4

Napisałem kod dla innego pytania, które jest podobne do tego, ale to pytanie zostało zduplikowane, więc nie mogę tam odpowiedzieć, więc umieszczam tutaj mój kod, jeśli ktoś szuka tego samego wymagania.

To nie jest w pełni działający kod, musisz wprowadzić drobne zmiany, aby działał.

Oto kod:

Skorzystałem z pomysłu @Graeme, aby używać spannable text.

String colorfulText = "colorfulText";       
    Spannable span = new SpannableString(colorfulText);             

    for ( int i = 0, len = colorfulText.length(); i < len; i++ ){
        span.setSpan(new ForegroundColorSpan(getRandomColor()), i, i+1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);                     
    }   

    ((TextView)findViewById(R.id.txtSplashscreenCopywrite)).setText(span);

Losowa metoda koloru:

  private int getRandomColor(){
        Random rnd = new Random();
        return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
    }
NaserShaikh
źródło
2

Spróbuj tego:

mBox = new TextView(context);
mBox.setText(Html.fromHtml("<b>" + title + "</b>" +  "<br />" + 
      "<small>" + description + "</small>" + "<br />" + 
      "<small>" + DateAdded + "</small>"));
user3579830
źródło
2

Tam, gdzie to możliwe, należy używać klasy SpannableBuilder zamiast formatowania HTML, ponieważ jest to szybsze niż analizowanie formatu HTML. Zobacz mój własny test porównawczy „SpannableBuilder vs HTML” na Github Dzięki!

Anatoliy Shuba
źródło
1

Niesamowite odpowiedzi! Udało mi się użyć Spannable do zbudowania tekstu w kolorze tęczy (więc można to powtórzyć dla dowolnej tablicy kolorów). Oto moja metoda, jeśli komuś pomoże:

private Spannable buildRainbowText(String pack_name) {
        int[] colors = new int[]{Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE};
        Spannable word = new SpannableString(pack_name);
        for(int i = 0; i < word.length(); i++) {
            word.setSpan(new ForegroundColorSpan(colors[i]), i, i+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return word;
    }

A potem po prostu setText (buildRainboxText (nazwa_paczki)); Zwróć uwagę, że wszystkie słowa, które przekazuję, mają mniej niż 15 znaków, a to po prostu powtarza 5 kolorów 3 razy - chcesz dostosować kolory / długość tablicy do swoich potrzeb!

Casey Murray
źródło
1
if (Build.VERSION.SDK_INT >= 24) {
     Html.fromHtml(String, flag) // for 24 API  and more
 } else {
     Html.fromHtml(String) // or for older API 
 }

dla 24 API i więcej (flaga)

public static final int FROM_HTML_MODE_COMPACT = 63;
public static final int FROM_HTML_MODE_LEGACY = 0;
public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1;
public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0;
public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1;

Więcej informacji

Ahmad Aghazadeh
źródło
1

Od API 24 masz FROM_HTML_OPTION_USE_CSS_COLORS, więc możesz definiować kolory w CSS zamiast powtarzać to za każdym razem z font color=" Dużo wyraźniejszym - kiedy masz trochę html i chcesz podświetlić jakieś predefiniowane tagi - wystarczy dodać fragment CSS na górze html

Filipkowicz
źródło
0

25 czerwca 2020 by @canerkaseler

Chciałbym podzielić się odpowiedzią Kotlin :

fun setTextColor(tv:TextView, startPosition:Int, endPosition:Int, color:Int){
    val spannableStr = SpannableString(tv.text)

    val underlineSpan = UnderlineSpan()
    spannableStr.setSpan(
        underlineSpan,
        startPosition,
        endPosition,
        Spanned.SPAN_INCLUSIVE_EXCLUSIVE
    )

    val backgroundColorSpan = ForegroundColorSpan(this.resources.getColor(R.color.agreement_color))
    spannableStr.setSpan(
        backgroundColorSpan,
        startPosition,
        endPosition,
        Spanned.SPAN_INCLUSIVE_EXCLUSIVE
    )

    val styleSpanItalic = StyleSpan(Typeface.BOLD)
    spannableStr.setSpan(
        styleSpanItalic,
        startPosition,
        endPosition,
        Spanned.SPAN_INCLUSIVE_EXCLUSIVE
    )

    tv.text = spannableStr
}

Następnie wywołaj powyższą funkcję. Możesz zadzwonić do więcej niż jednego:

setTextColor(textView, 0, 61, R.color.agreement_color)
setTextColor(textView, 65, 75, R.color.colorPrimary)

Wynik: możesz zobaczyć podkreślenie i różne kolory.

@canerkaseler

canerkaseler
źródło