Можно ли изменить цвет текста в строке на несколько цветов в Java?

Я имею в виду, можно ли изменить текст «Этот текст синий» на синий цвет в одной строке? Должен быть способ...

<TextView
    android:gravity="left"
    android:padding="3dip"
    android:text="This text is white. This text is blue."
    android:textColor="#ffffff"
    android:textSize="22dp"/>

person jmendegan    schedule 06.12.2011    source источник


Ответы (8)


Да, это возможно. Для этого вам нужно использовать SpannableString и ForegroundColorSpan.

Это должно выглядеть примерно так:

SpannableStringBuilder builder = new SpannableStringBuilder();

String red = "this is red";
SpannableString redSpannable= new SpannableString(red);
redSpannable.setSpan(new ForegroundColorSpan(Color.RED), 0, red.length(), 0);
builder.append(redSpannable);

String white = "this is white";
SpannableString whiteSpannable= new SpannableString(white);
whiteSpannable.setSpan(new ForegroundColorSpan(Color.WHITE), 0, white.length(), 0);
builder.append(whiteSpannable);

String blue = "this is blue";
SpannableString blueSpannable = new SpannableString(blue);
blueSpannable.setSpan(new ForegroundColorSpan(Color.BLUE), 0, blue.length(), 0);
builder.append(blueSpannable);

mTextView.setText(builder, BufferType.SPANNABLE);

введите здесь описание изображения

person inazaruk    schedule 06.12.2011
comment
Вы забыли указать тип буфера в последней строке - person Jason Robinson; 06.12.2011
comment
Просто любопытно... Нужно ли это делать в отдельном классе? Я работаю с Android, поэтому он должен быть в классе MainActivity? - person jmendegan; 06.12.2011
comment
Если хотите, можете пойти в отдельный класс. Но это может быть и в MainActivity. На это нет ограничений, но вам необходимо иметь доступ к TextView, на который вы хотите установить SpannableString. - person inazaruk; 06.12.2011
comment
@ jrobinson3k1, в моем случае он работает без буфера. Но я все же считаю, что лучше указать BufferType. Спасибо за исправление. - person inazaruk; 06.12.2011
comment
@inazaruk Приятно знать, что TextView автоматически определит переданный тип, если вы его не укажете. Я всегда просто указывал, поэтому я никогда не знал. Спасибо. - person Jason Robinson; 06.12.2011
comment
Как бы вы сделали это для цвета И стиля (курсив или полужирный) одновременно? - person SMBiggs; 05.02.2013
comment
У меня не работает android 7.0 в AlertDialog setMessage() - person Nitesh Verma; 22.03.2017

Простой способ сделать это — использовать HTML и программно установить текст в TextView.

String text = "This text is white. <font color=\"blue\">This text is blue.</font>";
textView.setText(Html.fromHtml(text), BufferType.SPANNABLE);
person Jason Robinson    schedule 06.12.2011
comment
Что делать, если вы ссылаетесь на строку в string.xml? - person portfoliobuilder; 06.07.2015
comment
как передать строку внутри <font color=\"blue\">This text is blue.</font>"; - person Moeez; 27.05.2021

Попробуй это..

TextView update= (TextView) dialog.findViewById(R.id.address);
String colorText= "Driver is nearby "
                + "<font color=\"#E72A02\"><bold>"
                + "43, KR Rd, Tata Silk Farm, Jayanagar"
                + "</bold></font>"
                + " and he is "
                + "<font color=\"#B92000\"><bold>"
                + "11 km"
                + "</bold></font>"
                + " & "
                + "<font color=\"#B92000\"><bold>"
                + "20 mins"
                + "</bold></font>"
                + " away from your current location.";

        update.setText(Html.fromHtml(colorText));

и результат будет таким..

результат

person Silambarasan Poonguti    schedule 18.09.2014

Html.fromHtml(String) устарело в Android N

Для поддержки последней версии Android, что-то вроде этого

 val colorText = ("Some Normal Text\n" 
                    + "<font color=\"#FFA500\"><bold> Orange Text </bold></font>"
                    + "More Normal text")

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            venueAddressValue.setText(Html.fromHtml(colorText, Html.FROM_HTML_MODE_LEGACY));
        } else {
            venueAddressValue.setText(Html.fromHtml(colorText));
        }
person Hitesh Sahu    schedule 18.06.2018

Я создал такой класс:

import android.text.SpannableStringBuilder;
import android.text.style.CharacterStyle;

public class StyleableSpannableStringBuilder extends SpannableStringBuilder {
    public StyleableSpannableStringBuilder appendWithStyle(CharacterStyle c, CharSequence text) {
        super.append(text);
        int startPos = length() - text.length();
        setSpan(c, startPos, length(), 0);
        return this;
    }

    public StyleableSpannableStringBuilder appendWithStyle(CharacterStyle [] c, CharSequence text) {
        super.append(text);
        int startPos = length() - text.length();
        for (CharacterStyle c1 : c)
            setSpan(c1, startPos, length(), 0);         
        return this;
    }       
}

Это позволяет мне делать такие вещи:

private void buildTickerItem(DelayedQuoteServiceObject o)
{   
    Double lastPrice = Double.parseDouble(o.getValue("LastPrice"));
    Double dayChange = Double.parseDouble(o.getValue("DayChange"));
    Double percentChange = Double.parseDouble(o.getValue("PercentDayChange")) / 100;

    if (o.isIndex() == true)
    {

        tickerTapeData.appendWithStyle(new StyleSpan(Typeface.BOLD),o.getDisplayName());            
        tickerTapeData.append(" "+ indexFormat.format(lastPrice) + " (");

        if (dayChange >= 0)
            tickerTapeData.appendWithStyle(new ForegroundColorSpan(Colours.getTickerPositive()), indexFormat.format(dayChange));        
        else
            tickerTapeData.appendWithStyle(new ForegroundColorSpan(Color.RED), indexFormat.format(dayChange));
    }
    else
    {
        tickerTapeData.appendWithStyle(new StyleSpan(Typeface.BOLD), o.ticker);

        tickerTapeData.append("@"+ dollarFormat.format(lastPrice) + " (");              

        if (dayChange >= 0)
            tickerTapeData.appendWithStyle(new ForegroundColorSpan(Colours.getTickerPositive()), dollarFormat.format(dayChange));       
        else
            tickerTapeData.appendWithStyle(new ForegroundColorSpan(Color.RED), dollarFormat.format(dayChange));


    }

    tickerTapeData.append("/");


    if (dayChange >= 0)
        tickerTapeData.appendWithStyle(new ForegroundColorSpan(Colours.getTickerPositive()), percentFormat.format(percentChange));      
    else
        tickerTapeData.appendWithStyle(new ForegroundColorSpan(Color.RED), percentFormat.format(percentChange));

    tickerTapeData.append(")  ");       
}

Для создания бегущей строки. Работает довольно хорошо и сохраняет код в чистоте.

person knaak    schedule 06.12.2011
comment
Я снова должен спросить, как вы добавляете несколько стилей одновременно? Например, предположим, что вы хотите отобразить некоторые слова синим цветом, некоторые курсивом, а некоторые и тем, и другим? - person SMBiggs; 05.02.2013
comment
Скотт, он принимает массив CharacterStyles, поэтому вы можете вызвать appendWithStyle(new CharacterStyle[] { new ForegroundColorSpan(BLUE), new StyleSpan(ITALICS)}, текст, выделенный курсивом Blue); - person knaak; 28.02.2013

Вы можете попробовать это: Во фрагменте:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

View rootView = inflater.inflate(
                R.layout.shipment_accepted_fragment,
                container, false);

        String email = "([email protected])";

        TextView shipment_email = (TextView) rootView
                .findViewById(R.id.textview);
        String text_shipment_email = "Hello"
                + " <font color='"
                + getResources().getColor(R.color.green_color) + "'>" + email
                + "</font>"
                + "Bye";
        shipment_email.setText(Html.fromHtml(text_shipment_email),
                TextView.BufferType.SPANNABLE);
}
person Maddy    schedule 10.10.2014

Я использую для изменения звездочку, если услуга "Вперед"

String c = "*" + getResources().getString(R.string.rupee) + str_pay_at_store;
SpannableString spannable2 = new SpannableString(c);
spannable2.setSpan(new ForegroundColorSpan(Color.RED), 0, 1, 
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tv_payatstore.setText(spannable2);

Вы можете видеть вот так

введите здесь описание изображения

person Dhaval Shingala    schedule 16.05.2017

Это действительно просто. Просто добавьте их в свое значение/string.xml

<String name = 'name_of_the_String'><font color='#000000'>This is black</font><font color='#ffffff'>This is white</font></string>

Затем добавьте имя этой строки в файл ресурсов XML.

person F.K    schedule 08.08.2020