Возможно ли иметь несколько стилей внутри TextView? - PullRequest
524 голосов
/ 07 октября 2009

Можно ли установить несколько стилей для разных фрагментов текста внутри TextView?

Например, я задаю текст следующим образом:

tv.setText(line1 + "\n" + line2 + "\n" + word1 + "\t" + word2 + "\t" + word3);

Возможно ли иметь разные стили для каждого элемента текста? Например, жирная строка 1, курсивное слово 1 и т. Д.

Руководство разработчика Общие задачи и как их выполнять в Android включает Выбор, выделение или стилизация частей текста :

// Get our EditText object.
EditText vw = (EditText)findViewById(R.id.text);

// Set the EditText's text.
vw.setText("Italic, highlighted, bold.");

// If this were just a TextView, we could do:
// vw.setText("Italic, highlighted, bold.", TextView.BufferType.SPANNABLE);
// to force it to use Spannable storage so styles can be attached.
// Or we could specify that in the XML.

// Get the EditText's internal text storage
Spannable str = vw.getText();

// Create our span sections, and assign a format to each.
str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new BackgroundColorSpan(0xFFFFFF00), 8, 19, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 21, str.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Но для этого используются явные номера позиций внутри текста. Есть ли более чистый способ сделать это?

Ответы [ 18 ]

6 голосов
/ 03 сентября 2015

Вот простой способ сделать это, используя HTMLBuilder

    myTextView.setText(new HtmlBuilder().
                    open(HtmlBuilder.Type.BOLD).
                    append("Some bold text ").
                    close(HtmlBuilder.Type.BOLD).
                    open(HtmlBuilder.Type.ITALIC).
                    append("Some italic text").
                    close(HtmlBuilder.Type.ITALIC).
                    build()
    );

Результат:

Текст, выделенный жирным шрифтом Текст, выделенный курсивом

2 голосов
/ 14 ноября 2017

Я тоже

Как насчет использования красивой разметки с Kotlin и Anko -

import org.jetbrains.anko.*
override fun onCreate(savedInstanceState: Bundle?) {
    title = "Created with Beautiful Markup"
    super.onCreate(savedInstanceState)

    verticalLayout {
        editText {
            hint = buildSpanned {
                append("Italic, ", Italic)
                append("highlighted", backgroundColor(0xFFFFFF00.toInt()))
                append(", Bold", Bold)
            }
        }
    }
}

Created with Beautiful Markup

0 голосов
/ 27 июня 2019

Да, это возможно, используя SpannedString. Если вы используете Kotlin, это будет еще проще сделать с помощью core-ktx, поскольку он обеспечивает домен-специфический язык (DSL) для этого:

val string: SpannedString = buildSpannedString {
    bold {
        append("1111")
    }
    append("neil)     
}

Дополнительные опции:

append("Hello There")
bold {
    append("bold")
    italic {
        append("bold and italic")
        underline {
            append("then some text with underline")
        }
    }
}

Наконец, вы можете просто:

textView.text = string
0 голосов
/ 18 октября 2017

Как сказал Джон , для меня это лучшее решение, и вам не нужно задавать текст во время выполнения, используйте только этот пользовательский класс HtmlTextView

public class HtmlTextView extends TextView {

  public HtmlTextView(Context context) {
      super(context);
  }

  public HtmlTextView(Context context, AttributeSet attrs) {
      super(context, attrs);
  }

  public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr) 
  {
      super(context, attrs, defStyleAttr);
  }

  @TargetApi(21)
  public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
      super(context, attrs, defStyleAttr, defStyleRes);
  }

  @Override
  public void setText(CharSequence s,BufferType b){
      super.setText(Html.fromHtml(s.toString()),b);
  }

}

и все, теперь только поместите это в ваш XML

<com.fitc.views.HtmlTextView
    android:id="@+id/html_TV"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/example_html" />

с вашей строкой HTML

<string name="example_html">
<![CDATA[
<b>Author:</b> Mr Donuthead<br/>
<b>Contact:</b> me@donut.com<br/>
<i>Donuts for life </i>
]]>

0 голосов
/ 17 августа 2017

Spanny облегчает использование SpannableString.

Spanny spanny = new Spanny("Underline text", new UnderlineSpan())
                .append("\nRed text", new ForegroundColorSpan(Color.RED))
                .append("\nPlain text");
textView.setText(spanny)
0 голосов
/ 08 июня 2017

Использование вспомогательного класса Spannable в качестве Android String Resources делится в нижней части веб-страницы. Вы можете подойти к этому, создав CharSquences и придав им стиль.

Но в приведенном нами примере это просто жирный, курсив и даже раскраска текста. Мне нужно было обернуть несколько стилей в CharSequence, чтобы установить их в TextView. Итак, к этому классу (я назвал его CharSequenceStyles) я просто добавил эту функцию.

public static CharSequence applyGroup(LinkedList<CharSequence> content){
    SpannableStringBuilder text = new SpannableStringBuilder();
    for (CharSequence item : content) {
        text.append(item);
    }
    return text;
}

И в представлении я добавил это.

            message.push(postMessageText);
            message.push(limitDebtAmount);
            message.push(pretMessageText);
            TextView.setText(CharSequenceStyles.applyGroup(message));

Надеюсь, это поможет вам!

0 голосов
/ 11 августа 2014

Фактически, кроме объекта Html, вы также можете использовать классы типов Spannable, например, TextAppearanceSpan или TypefaceSpan и SpannableString вместе. Класс HTML также использует эти механизмы. Но с классами Spannable вы получаете больше свободы.

0 голосов
/ 11 августа 2016

Это может быть так же просто, как использовать метод length () строки:

  1. Разбейте текстовую строку в XML-файле Strings на столько подстрок (отдельных строк с точки зрения Android), сколько вам нужно разных стилей, так что это может выглядеть так: str1, str2 , str3 (как в вашем случае), которые при объединении представляют собой целую строку, которую вы используете.

  2. А затем просто следуйте методу «Span», точно так же, как вы представили свой код - но вместо одной строки объедините все подстроки, объединяя их в одну, каждая со своим собственным стилем.

Вы по-прежнему используете числа, но не напрямую - они больше не принимают жестко закодированную форму (как в вашем коде) сейчас, но они заменяются комбинированными методами length () (обратите внимание на две звезды перед и после суффикса str.length () вместо абсолютного числа, чтобы погасить изменение):

str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, **str.length()**, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

для первого размера строки, затем str.length () + 1, str.length () + str2.length () для второго размера строки и т. Д. Со всеми подстроками вместо например 0,7 или 8,19 и так далее ...

...