Один TextView с многоцветным текстом

168

Как видно из заголовка, я хочу знать, возможно ли получить два разноцветных символа в одном элементе textview.

Андро Сельва
источник
1
Это не дубликат, так как спрашивающий спрашивает цвет специально.
Икбал
Я думаю, что для этого есть хорошая библиотека: blog.stylingandroid.com/rialto-downloadable-fonts github.com/StylingAndroid/Rialto
разработчик для Android
я также написал некоторую библиотеку, поведение которой схоже с этим: github.com/ha-yi/MultiColorTextView
Хайи Нукман,

Ответы:

328

да, если вы отформатируете свойство Stringwith html, font-colorто передадите его методуHtml.fromHtml(your text here)

String text = "<font color=#cc0029>First Color</font> <font color=#ffcc00>Second Color</font>";
yourtextview.setText(Html.fromHtml(text));
2red13
источник
Спасибо также полезно для меня. +1
Хардик Джоши
10
Не забудьте выйти из пользовательского ввода используя Html.escapeHtml(str).
kelunik
1
Добавлено на уровне API 1
2red13
3
Просто предупреждение. У меня была проблема, когда мне нужно, чтобы мой текст был в верхнем регистре. Я использовал android: textAllCaps = "true" в XML и в то же время мой HTML-контент был в верхнем регистре. Это не сработало. Я удалил атрибут XML, и теперь он работает нормально. Будьте осторожны, потому что если вы используете setAllCaps () в коде, появится та же проблема.
joao2fast4u
5
Html.fromHtml(String)теперь устарела, вместо использования Html.fromHtml(String, Html.FROM_HTML_MODE_LEGACY). Более подробную информацию можно найти здесь.
JediBurrell
165

Вы можете печатать строки с несколькими цветами без HTML как:

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);
Свапнил котвал
источник
отлично, спасибо, тоже можно сделать BackgroundColorSpan. в вашем примере есть небольшая опечатка, WordToSpan и WordtoSpan, обратите внимание на случай с To
steveh
как можно выполнить модульное тестирование textview, чтобы убедиться, что текст заканчивается в Color.RED stackoverflow.com/questions/26611533/…
sudocoder
1
Не работает для меня получение `java.lang.StringIndexOutOfBoundsException: length = 3; index = 12`
Мухаммед Бабар
1
StringIndexOutOfBoundsException сама по себе пояснительная. Вы получаете доступ к строке за ее пределами.
Свопнил Котвал
1
Мои строки не были исправлены, поэтому строки будут генерироваться во время выполнения приложения. Я перепробовал почти все ответы на этот вопрос. Но только это решение работало для меня.
Г-жа Саббир Ахмед
33

Вы можете использовать Spannableдля применения эффектов к TextView:

Вот мой пример раскраски только первой части TextViewтекста (при этом вы можете установить цвет динамически, а не жестко кодировать его в строку, как в примере с 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);

В этом примере вы можете заменить 0xFFFF0000 на getResources().getColor(R.color.red)

Graeme
источник
1
Если вам нужен этот верхний регистр, просто toUpperCase () Strings.
Грэм
33

Я сделал так:

Проверьте ссылку

Установите цвет для текста , передав строку и цвет :

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

Установите текст в TextView / Button / EditText и т. Д., Вызвав код ниже:

TextView:

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

Получить цветную строку:

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

Установите Text для TextView двух строк с разными цветами:

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

Готово

Хирен Патель
источник
1
Нью-Йорк один, но HTml.fromHtml устарел в API 24
Anuraj R
Вы можете заменить звонки на Html.fromHtml("...")звонкиHtml.fromHtml("...", FROM_HTML_MODE_LEGACY)
stkent
31

Использовать 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);
Бисваджит Кармакар
источник
8

Эй, ребята, я сделал это, попробуйте

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

Внутри вашего класса TextViewUtils добавьте этот метод

 /***
 *
 * @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;
}
Абдул Ризван
источник
Я только что обновил, проверь один раз, у меня работает.
Абдул Ризван
Может, вы используете Html.fromHtml для использования этой строки?
Сергей Шустиков
Внутри файла string.xml я создал переменную и установил ее, она работает на меня только сейчас, я делаю это, не могли бы вы дать свою строку здесь.
Абдул Ризван
5

Лучше использовать строку в файле строк, как таковую:

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

Использование:

textView.text=HtmlCompat.fromHtml(getString(R.string.some_text), HtmlCompat.FROM_HTML_MODE_LEGACY)
разработчик Android
источник
4

Я записал некоторый код для другого вопроса, который похож на этот, но этот вопрос дублировался, поэтому я не могу ответить на него, поэтому я просто размещаю свой код здесь, если кто-то ищет такое же требование.

Это не полностью рабочий код, вам нужно внести небольшие изменения, чтобы он заработал.

Вот код:

Я использовал @Graeme идею использования связующего текста.

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

Метод случайного цвета:

  private int getRandomColor(){
        Random rnd = new Random();
        return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
    }
NaserShaikh
источник
2

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

mBox = new TextView(context);
mBox.setText(Html.fromHtml("<b>" + title + "</b>" +  "<br />" + 
      "<small>" + description + "</small>" + "<br />" + 
      "<small>" + DateAdded + "</small>"));
user3579830
источник
2

Используйте класс SpannableBuilder вместо форматирования HTML, где это возможно, потому что это быстрее, чем анализ формата HTML. Смотрите мой собственный тест "SpannableBuilder vs HTML" на Github. Спасибо!

Анатолий Шуба
источник
1

Потрясающие ответы! Я смог использовать Spannable для создания текста цвета радуги (так что это можно повторить для любого массива цветов). Вот мой метод, если он кому-нибудь поможет:

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

И тогда я просто setText (buildRainboxText (pack_name)); Обратите внимание, что все слова, которые я передаю, имеют длину до 15 символов, и это просто повторяет 5 цветов 3 раза - вы хотите настроить цвета / длину массива для своего использования!

Кейси Мюррей
источник
1
if (Build.VERSION.SDK_INT >= 24) {
     Html.fromHtml(String, flag) // for 24 API  and more
 } else {
     Html.fromHtml(String) // or for older API 
 }

для 24 API и более (флаг)

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;

Больше информации

Ахмад Агазаде
источник
1

Начиная с API 24 у вас есть FROM_HTML_OPTION_USE_CSS_COLORS, так что вы можете определять цвета в CSS вместо того, чтобы повторять это все время с font color=" гораздо более понятным - когда у вас есть немного HTML и вы хотите выделить некоторые предопределенные теги - вам просто нужно добавить фрагмент CSS в верхней части вашего HTML

Filipkowicz
источник
0

25 июня 2020 года @canerkaseler

Я хотел бы поделиться 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
}

После вызова вышеуказанной функции. Вы можете позвонить более чем одному:

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

Вывод: Вы можете видеть подчеркивание и разные цвета друг с другом.

@canerkaseler

canerkaseler
источник