SpannableStringBuilder для создания String с несколькими шрифтами/размерами текста и т.д. Пример?

Мне нужно создать String, помещенную в TextView, которая отобразит такую ​​строку:

Первая часть не жирная BOLD не выделяется жирным шрифтом

Итак, я хочу знать, как я мог бы использовать SpannableStringBuilder для этого?

Я мог бы использовать три TextEdit для этого, но я бы хотел использовать лучшее решение.

Ответ 1

First Part Not Bold   BOLD  rest not bold

Вы можете сделать это либо, как предложили @Rajesh, либо этим.

String normalBefore= "First Part Not Bold ";
String normalBOLD=  "BOLD ";
String normalAfter= "rest not bold";
String finalString= normalBefore+normalBOLD+normalAfter;
Spannable sb = new SpannableString( finalString );
sb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), finalString.indexOf(normalBOLD)+ normalBOLD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //bold
sb.setSpan(new AbsoluteSizeSpan(intSize), finalString.indexOf(normalBOLD)+ normalBOLD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//resize size

чтобы показать это в TextView

textview.setText(sb);

Ответ 2

Принятый ответ прекрасен (и я его поддержал), но он не может использовать SpannableStringBuilder в качестве запрашиваемого. Поскольку у меня был случай, когда Builder имел наибольший смысл, вот код для этого (при использовании бонуса также меняется цвет текста, если это полезно для других). Обратите внимание, что вы также можете предоставить начальную строку конструктору SpannableStringBuilder, но я установил его здесь, чтобы использовать "append", чтобы быть ясным, что вы можете добавить много до вашего желаемого "жирного" текста, а затем просто записать начало, как показано. Я подозреваю, что это также более быстрый код, чем принятый ответ.

SpannableStringBuilder longDescription = new SpannableStringBuilder();
longDescription.append("First Part Not Bold ");
int start = longDescription.length();
longDescription.append("BOLD");
longDescription.setSpan(new ForegroundColorSpan(0xFFCC5500), start, longDescription.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
longDescription.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), start, longDescription.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
longDescription.append(" rest not bold");

Ответ 3

Из API 21 SpannableStringBuilder включает простой способ сделать это. Вот пример решения:

SpannableStringBuilder builder= new SpannableStringBuilder();
StyleSpan boldSpan = new StyleSpan(android.graphics.Typeface.BOLD);
builder.append("First Part Not Bold ")
              .append("BOLD ", boldSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
              .append("rest not bold");

Так как это хороший шанс, что вы не поддерживаете API 21, вы можете дублировать код из этого метода:

public SpannableStringBuilder append(CharSequence text, Object what, int flags) {
        int start = length();
        append(text);
        setSpan(what, start, length(), flags);
        return this;
}

Ответ 4

Используйте HTML-код в TextView, используя Html класс:

Spanned styledText = Html.fromHtml("First Part Not Bold <b>BOLD</b> rest not bold");
textView.setText(styledText);

Ответ 5

Итак, я знаю, что это было решено и даже запрошено с помощью SpannableStringBuilder, но в случае, если вы хотели бы построить строку более динамично, я решил, что я это рассмотрю.

// Stuff needed
TextView DataTextView = (TextView)rootView.findViewById(R.id.DataView);
String Fields[] = {...database column names as strings... "x","y"};

String DataString = new String();   

int start,stop;     // Start and Stop of formatting

// Final Result
SpannableStringBuilder coloredString = new SpannableStringBuilder(); 

SpannableString temp;       // Small segment of colored string
for (int i =0; i < Fields.length; i++)
{
    if (database_result.containsKey(Fields[i]))  // Be sure a field exists in the ContentValues
    {
            DataString = Fields[i]+": ";
        start = DataString.length();
        DataString = DataString+ +database_result.getAsInteger(Fields[i])+" ";
        stop= DataString.length();
        temp = new SpannableString(DataString);
        temp.setSpan(new ForegroundColorSpan(Color.WHITE),start, stop, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        coloredString.append(temp);
    }   
}
DataTextView.setText(coloredString);

database_result - это тип ContentValues, который я создал из возвращаемого типа Cursor SQL-запроса. Единственная проблема, с которой я столкнулся, состояла в том, что сначала был только ColorSpaning первого сегмента. Это означает, что вам нужно объявить новый ForegroundColorSpan каждый раз, когда вы хотите использовать один (или любой другой тип диапазона) в цикле.

Ответ 6

В этом коде должно быть выделено все, что входит в ярлык html bold. И он также удаляет тег, поэтому отображается только содержимое внутри.

        SpannableStringBuilder sb = new SpannableStringBuilder("this is <b>bold</b> and this is <b>bold too</b>  and this is <b>bold too, again</b>.");

        Pattern p = Pattern.compile("<b>.*?</b>", Pattern.CASE_INSENSITIVE);            
        boolean stop = false;
        while (!stop)
        {
            Matcher m = p.matcher(sb.toString());
            if (m.find()) {
                sb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                sb.delete(m.end()-4, m.end());
                sb.delete(m.start(), m.start() + 3);
            }
            else
                stop = true;
        }

Этот код также может быть адаптирован для других тегов стиля html, таких как Superscript (sup tag) и т.д.

        SpannableStringBuilder sb = new SpannableStringBuilder("text has <sup>superscript</sup> tag");

        Pattern p = Pattern.compile("<sup>.*?</sup>", Pattern.CASE_INSENSITIVE);            
        boolean stop = false;
        while (!stop)
        {
            Matcher m = p.matcher(sb.toString());
            if (m.find()) {
                sb.setSpan(new SuperscriptSpan(), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                sb.delete(m.end()-6, m.end());
                sb.delete(m.start(), m.start() + 5);
            }
            else
                stop = true;
        }

Чтобы установить цвет, просто используйте ForegroundColorSpan с помощью setSpan.

sb.setSpan(new ForegroundColorSpan(Color.rgb(255, 0, 0)), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);

Надеюсь, что это поможет.

Ответ 7

Почему вы используете SpannableStringBuilder, когда можете использовать SpannableBuilder? (https://gist.github.com/qtyq/90f9b4894069a8b3676c)

SpannableString ss = SpannableBuilder.init("First Part Not Bold BOLD rest not bold")
                                     .makeBold("BOLD")
                                     .create()

Ответ 8

Мы также можем использовать SpannableStringBuilder с TextAppearanceSpan для этого. Следуйте приведенным ниже инструкциям, чтобы реализовать это.

  • Создайте стиль в styles.xml.

<style name="BoldStyle">
   <!-- Can add other styling attributes -->
   <item name="android:textStyle">bold</item>
   ......
</style>