Установить цвет диапазона TextView в Android

Можно ли установить цвет только диапазона текста в TextView?

Я хотел бы сделать что-то похожее на приложение Twitter, в котором часть текста выделена синим цветом. См. изображение ниже:

alt text
(источник: twimg .com)


person hpique    schedule 19.07.2010    source источник


Ответы (16)


Другой ответ был бы очень похож, но не нужно было бы дважды устанавливать текст TextView

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);
person DanO    schedule 18.08.2010
comment
но как я могу изменить цвет для нескольких слов, в которых я набираю весь текст, а не один диапазон? - person mostafa hashim; 08.11.2015
comment
@mostafahashim создает несколько диапазонов, повторяя строку 3 wordtoSpan.setSpan(new ForegroundColorSpan(Color.RED), 50, 80, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - person Ashraf Alshahawy; 05.01.2016
comment
Решение Kotlin + Spannable String будет выглядеть следующим образом: 59510004#59510004" title="как изменить цвет части текстового представления"> stackoverflow.com/questions/4032676/ - person Dmitrii Leonov; 01.01.2020

Вот небольшая функция помощи. Отлично, когда у вас есть несколько языков!

private void setColor(TextView view, String fulltext, String subtext, int color) {
    view.setText(fulltext, TextView.BufferType.SPANNABLE);
    Spannable str = (Spannable) view.getText();
    int i = fulltext.indexOf(subtext);
    str.setSpan(new ForegroundColorSpan(color), i, i + subtext.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
person mach    schedule 19.05.2011

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

Фоновый цвет

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

SpannableString spannableString = new SpannableString("Hello World!");
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.YELLOW);
spannableString.setSpan(backgroundSpan, 0, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);

Цвет переднего плана

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

SpannableString spannableString = new SpannableString("Hello World!");
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
spannableString.setSpan(foregroundSpan, 0, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);

Комбинация

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

SpannableString spannableString = new SpannableString("Hello World!");
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.YELLOW);
spannableString.setSpan(foregroundSpan, 0, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(backgroundSpan, 3, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);

Дальнейшее обучение

person Suragch    schedule 31.01.2017
comment
Как я могу добавить пышный фон сюда??? - person Gk Mohammad Emon; 03.05.2021
comment
@GkMohammadEmon, это похоже на индивидуальную роспись, а не на простой цвет фона. Посмотрите кривые Безье. - person Suragch; 03.05.2021
comment
Есть ли у вас хорошие ссылки или ресурсы об этом? Мне нужно добавить изогнутый фон моей кнопки действия уведомления. Спасибо за ваш ответ - person Gk Mohammad Emon; 03.05.2021
comment
@GkMohammadEmon, извини, что нет. Прошло много времени с тех пор, как я рисовал на Android с тех пор, как перешел на Flutter. - person Suragch; 03.05.2021

Если вам нужен больший контроль, вы можете проверить класс TextPaint. Вот как это использовать:

final ClickableSpan clickableSpan = new ClickableSpan() {
    @Override
    public void onClick(final View textView) {
        //Your onClick code here
    }

    @Override
    public void updateDrawState(final TextPaint textPaint) {
        textPaint.setColor(yourContext.getResources().getColor(R.color.orange));
        textPaint.setUnderlineText(true);
    }
};
person Bitcoin Cash - ADA enthusiast    schedule 27.02.2014
comment
getColor(int id) устарел в Android 6.0 Marshmallow (API 23) 23" title="идентификатор getcolorint устарел на Android 6 0 зефир API 23"> stackoverflow.com/questions/31590714/ - person Eka putra; 06.12.2017
comment
Хороший ответ с Click Listener. - person Muhaiminur Rahman; 12.06.2019

Настройте свой текст TextView как расширяемый и определите ForegroundColorSpan для вашего текста.

TextView textView = (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);    
textView.setText(wordtoSpan);
person Jorgesys    schedule 19.07.2010
comment
Спасибо! Можно ли сделать это, не назначая сначала текст TextView? - person hpique; 19.07.2010
comment
Я плохо объяснил. Позвольте мне перефразировать. Нужны ли первые 3 строки? Разве вы не можете напрямую создать объект Spannable из строки? - person hpique; 20.07.2010
comment
Нет, вам нужно сохранить текст TextView в Buffer Spannable, чтобы изменить цвет переднего плана. - person Jorgesys; 20.07.2010
comment
Я хочу сделать то же самое с цветом, плюс я хочу, чтобы все было жирным, кроме цветной части, которую я хочу выделить курсивом, как я могу это сделать? - person Lukap; 02.07.2011
comment
как установить щелчок в диапазоне? - person Rishabh Srivastava; 07.08.2015

Другой способ, который можно использовать в некоторых ситуациях, — установить цвет ссылки в свойствах представления, которое принимает Spannable.

Например, если ваш Spannable будет использоваться в TextView, вы можете установить цвет ссылки в XML следующим образом:

<TextView
    android:id="@+id/myTextView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColorLink="@color/your_color"
</TextView>

Вы также можете установить его в коде с помощью:

TextView tv = (TextView) findViewById(R.id.myTextView);
tv.setLinkTextColor(your_color);
person Dave    schedule 09.08.2012

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

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

Установите текст в TextView/Button/EditText и т. д., вызвав следующий код:

Просмотр текста:

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

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

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

Установить текст в TextView:

txtView.setText(Html.fromHtml(name));

Готово

person Hiren Patel    schedule 16.06.2015

Есть фабрика для создания Spannable и избегайте приведения, например:

Spannable span = Spannable.Factory.getInstance().newSpannable("text");
person Thomas Emil Hansen    schedule 13.12.2011
comment
Не могли бы вы уточнить, как использовать SpannableFactory? Как должен выглядеть текст? - person Piotr; 03.10.2012
comment
после создания Spannable с помощью SpannableFactory, так как его использовать? - person MBH; 22.09.2016

Вот функция расширения Kotlin, которая у меня есть для этого

    fun TextView.setColouredSpan(word: String, color: Int) {
        val spannableString = SpannableString(text)
        val start = text.indexOf(word)
        val end = text.indexOf(word) + word.length
        try {
            spannableString.setSpan(ForegroundColorSpan(color), start, end,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            text = spannableString
        } catch (e: IndexOutOfBoundsException) {
         println("'$word' was not not found in TextView text")
    }
}

Используйте его после того, как вы установили свой текст в TextView следующим образом

private val blueberry by lazy { getColor(R.color.blueberry) }

textViewTip.setColouredSpan("Warning", blueberry)
person Ivan Wooll    schedule 27.11.2018
comment
Большое спасибо, дружище, ты делаешь мой день :* - person Ahsan Syed; 19.03.2021
comment
Должен быть лучший ответ для реализации Kotlin. - person Oleksandr Bodashko; 08.06.2021

Просто чтобы добавить к принятому ответу, так как все ответы говорят о android.graphics.Color только: что, если цвет, который я хочу, определен в res/values/colors.xml?

Например, рассмотрим цвета Material Design, определенные в colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="md_blue_500">#2196F3</color>
</resources>

(android_material_design_colours.xml — ваш лучший друг)

Затем используйте ContextCompat.getColor(getContext(), R.color.md_blue_500) вместо Color.BLUE, чтобы:

wordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

становится:

wordtoSpan.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.md_blue_500)), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Где я это нашел:

person Antônio Medeiros    schedule 15.08.2018

String text = "I don't like Hasina.";
textView.setText(spannableString(text, 8, 14));

private SpannableString spannableString(String text, int start, int end) {
    SpannableString spannableString = new SpannableString(text);
    ColorStateList redColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{0xffa10901});
    TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, redColor, null);

    spannableString.setSpan(highlightSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannableString.setSpan(new BackgroundColorSpan(0xFFFCFF48), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannableString.setSpan(new RelativeSizeSpan(1.5f), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    return spannableString;
}

Вывод:

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

person Ahamadullah Saikat    schedule 23.12.2017
comment
тебе не нравится Хасина ???? - person Abu Nayem; 09.05.2020

Диапазон просмотра текста

Используя kotlin-ktx, вы легко добьетесь этого.

        bindView?.oneTimePasswordTitle?.text = buildSpannedString {
        append("One Time Password ")
        inSpans(
            ForegroundColorSpan(ContextCompat.getColor(bindView?.oneTimePasswordTitle?.context!!,R.color.colorPrimaryText))
        ){
            append(" (As Registered Email)")
        }

    }
person Ashwin Nirmale    schedule 25.05.2021

  1. создать текстовое представление в вашем макете
  2. вставьте этот код в ur MainActivity

    TextView textview=(TextView)findViewById(R.id.textviewid);
    Spannable spannable=new SpannableString("Hello my name is sunil");
    spannable.setSpan(new ForegroundColorSpan(Color.BLUE), 0, 5, 
    Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    textview.setText(spannable);
    //Note:- the 0,5 is the size of colour which u want to give the strring
    //0,5 means it give colour to starting from h and ending with space i.e.(hello), if you want to change size and colour u can easily
    
person Sunil    schedule 07.04.2017

Некоторые ответы здесь не актуальны. Потому что вы (в большинстве случаев) добавите пользовательское действие при нажатии на ссылку.

Кроме того, как указано в справке по документации, цвет вашей ссылки на составную строку будет иметь цвет по умолчанию. "Цветом ссылки по умолчанию является цвет акцента темы или android:textColorLink, если этот атрибут определен в теме".

Вот способ сделать это безопасно.

 private class CustomClickableSpan extends ClickableSpan {

    private int color = -1;

    public CustomClickableSpan(){
        super();
        if(getContext() != null) {
            color = ContextCompat.getColor(getContext(), R.color.colorPrimaryDark);
        }
    }

    @Override
    public void updateDrawState(@NonNull TextPaint ds) {
        ds.setColor(color != -1 ? color : ds.linkColor);
        ds.setUnderlineText(true);
    }

    @Override
    public void onClick(@NonNull View widget) {
    }
}

Потом использовать.

   String text = "my text with action";
    hideText= new SpannableString(text);
    hideText.setSpan(new CustomClickableSpan(){

        @Override
        public void onClick(@NonNull View widget) {
            // your action here !
        }

    }, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    yourtextview.setText(hideText);
    // don't forget this ! or this will not work !
    yourtextview.setMovementMethod(LinkMovementMethod.getInstance());

Надеюсь, это сильно поможет!

person Zhar    schedule 21.04.2020

Из документации разработчика, чтобы изменить цвет и размер spannable:

1- создать класс:

    class RelativeSizeColorSpan(size: Float,@ColorInt private val color: Int): RelativeSizeSpan(size) {

    override fun updateDrawState(textPaint: TextPaint?) {
        super.updateDrawState(textPaint)
        textPaint?.color = color
    } 
}

2 Создайте свой spannable, используя этот класс:

    val spannable = SpannableStringBuilder(titleNames)
spannable.setSpan(
    RelativeSizeColorSpan(1.5f, Color.CYAN), // Increase size by 50%
    titleNames.length - microbe.name.length, // start
    titleNames.length, // end
    Spannable.SPAN_EXCLUSIVE_INCLUSIVE
)
person fullmoon    schedule 21.04.2020

Ниже работает отлично для меня

    tvPrivacyPolicy = (TextView) findViewById(R.id.tvPrivacyPolicy);
    String originalText = (String)tvPrivacyPolicy.getText();
    int startPosition = 15;
    int endPosition = 31;

    SpannableString spannableStr = new SpannableString(originalText);
    UnderlineSpan underlineSpan = new UnderlineSpan();
    spannableStr.setSpan(underlineSpan, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

    ForegroundColorSpan backgroundColorSpan = new ForegroundColorSpan(Color.BLUE);
    spannableStr.setSpan(backgroundColorSpan, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

    StyleSpan styleSpanItalic  = new StyleSpan(Typeface.BOLD);

    spannableStr.setSpan(styleSpanItalic, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

    tvPrivacyPolicy.setText(spannableStr);

Вывод для приведенного выше кода

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

person OmiK    schedule 13.03.2020