Установить текст TextView из html-форматированного строкового ресурса в XML

У меня есть некоторые фиксированные строки внутри моего strings.xml , что-то вроде:

 <resources> <string name="somestring"> <B>Title</B><BR/> Content </string> </resources> 

И в моем макете у меня есть TextView который я хотел бы заполнить строкой в ​​формате html.

 <TextView android:id="@+id/formattedtext" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/htmlstring"/> 

Если я это сделаю, содержимое formattedtext somestring – это просто содержимое somestring лишенное любых html-тегов и, таким образом, неформатировано.

Я знаю, что программный текст можно форматировать с помощью

.setText(Html.fromHtml(somestring));

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

Для вызова этой функции мне нужна Activity , но на данный момент мой макет – это просто более или менее статический вид в простом XML, и я бы предпочел оставить его таким образом, чтобы избавить меня от накладных расходов на создание Activity только для Установите некоторый текст.

Я не замечаю ничего очевидного? Разве это вообще невозможно? Любая помощь или обходные пути приветствуются!

Edit: Просто попробовал кое-что, и кажется, что форматирование HTML в xml имеет некоторые ограничения:

  • Теги должны быть записаны в нижнем регистре

  • Некоторые теги, которые упоминаются здесь , не работают, например, <br/> (вместо этого можно использовать \n )

Solutions Collecting From Web of "Установить текст TextView из html-форматированного строкового ресурса в XML"

На всякий случай кто-нибудь найдет это, есть более приятная альтернатива, которая не документирована (я споткнулся о ней после поиска часов и, наконец, нашел ее в списке ошибок для Android SDK). Вы можете включить необработанный HTML-файл в strings.xml, если вы его оберните

 <![CDATA[ ...raw html... ]]> 

Пример:

 <string name="nice_html"> <![CDATA[ <p>This is a html-formatted string with <b>bold</b> and <i>italic</i> text</p> <p>This is another paragraph of the same string.</p> ]]> </string> 

Затем в вашем коде:

 TextView foo = (TextView)findViewById(R.id.foo); foo.setText(Html.fromHtml(getString(R.string.nice_html))); 

ИМХО, на несколько порядков лучше работать с 🙂

Поскольку главный ответ здесь предполагает что-то неправильное (или, по крайней мере, слишком сложное), я считаю, что это должно быть обновлено, хотя вопрос довольно старый:

При использовании ресурсов String в Android вам просто нужно вызвать getString(...) из кода Java или использовать android:text="@string/..." в вашем XML-макете.

Даже если вы хотите использовать разметку HTML в своих строках, вам не нужно много менять:

Единственными символами, которые вам нужно избежать в ваших ресурсах String, являются:

  • Двойной кавычек: " становится \"
  • Одинарная кавычка: ' становится \'
  • Амперсанд: & становится &#38; Или &amp;

Это означает, что вы можете добавить свою разметку HTML без экранирования тегов:

 <string name="my_string"><b>Hello World!</b> This is an example.</string> 

Однако, конечно, вы должны использовать только <b> , <i> и <u> как они указаны в документации.

Если вы хотите использовать ваши строки HTML из XML , просто продолжайте использовать android:text="@string/..." , он будет работать нормально.

Единственное различие заключается в том, что если вы хотите использовать ваши строки HTML из кода Java , вы должны использовать getText(...) вместо getString(...) сейчас, так как первый сохраняет стиль, а последний просто сбрасывает это от.

Это так просто. Нет CDATA, нет Html.fromHtml(...) .

Вам понадобится только Html.fromHtml(...) если вы кодировали специальные символы в разметке HTML. Затем используйте его с getString(...) . Это может быть необходимо, если вы хотите передать String в String.format(...) .

Все это описано в документах .

Редактировать:

Нет никакой разницы между getText(...) с невыбранным HTML (как я предложил) или разделами CDATA и Html.fromHtml(...) .

См. Следующий рисунок для сравнения:

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

Побег HTML-тегов …

 <resources> <string name="somestring"> &lt;B&gt;Title&lt;/B&gt;&lt;BR/&gt; Content </string> </resources> 

Android не имеет спецификации для указания типа строки ресурса (например, text / plain или text / html). Однако есть обходное решение, которое позволит разработчику указать это в XML-файле.

  1. Определите настраиваемый атрибут, чтобы указать, что атрибут android: text – html.
  2. Используйте подклассу TextView.

После того, как вы их определите, вы можете выразить HTML с помощью xml-файлов, не требуя снова вызвать setText (Html.fromHtml (…)). Я довольно удивлен, что этот подход не является частью API.

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

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

Res / values ​​/ strings.xml (строковый ресурс как HTML)

 <resources> <string name="app_name">TextViewEx</string> <string name="string_with_html"><![CDATA[ <em>Hello</em> <strong>World</strong>! ]]></string> </resources> 

Layout.xml (только соответствующие части)

Объявите пространство имен пользовательских атрибутов и добавьте атрибут android_ex: isHtml. Также используйте подкласс TextView.

 <RelativeLayout ... xmlns:android_ex="http://schemas.android.com/apk/res-auto" ...> <tv.twelvetone.samples.textviewex.TextViewEx android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/string_with_html" android_ex:isHtml="true" /> </RelativeLayout> 

Res / values ​​/ attrs.xml (определить пользовательские атрибуты для подкласса)

  <resources> <declare-styleable name="TextViewEx"> <attr name="isHtml" format="boolean"/> <attr name="android:text" /> </declare-styleable> </resources> 

TextViewEx.java (подкласс TextView)

  package tv.twelvetone.samples.textviewex; import android.content.Context; import android.content.res.TypedArray; import android.support.annotation.Nullable; import android.text.Html; import android.util.AttributeSet; import android.widget.TextView; public TextViewEx(Context context, @Nullable AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextViewEx, 0, 0); try { boolean isHtml = a.getBoolean(R.styleable.TextViewEx_isHtml, false); if (isHtml) { String text = a.getString(R.styleable.TextViewEx_android_text); if (text != null) { setText(Html.fromHtml(text)); } } } catch (Exception e) { e.printStackTrace(); } finally { a.recycle(); } } } 

Последнее обновление:

Html.fromHtml (string); // устарел после версий Android N ..

Следующий код дает поддержку андроидам N и выше …

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { textView.setText(Html.fromHtml(yourHtmlString,Html.FROM_HTML_MODE_LEGACY)); } else { textView.setText(Html.fromHtml(yourHtmlString)); } 

У меня есть другой случай, когда у меня нет шансов поместить CDATA в xml, поскольку я получаю строку HTML с сервера.

Вот что я получаю с сервера:

 <p>The quick brown&nbsp;<br /> fox jumps&nbsp;<br /> over the lazy dog<br /> </p> 

Это кажется более сложным, но решение намного проще.

 private TextView textView; protected void onCreate(Bundle savedInstanceState) { ..... textView = (TextView) findViewById(R.id.text); //need to define in your layout String htmlFromServer = getHTMLContentFromAServer(); textView.setText(Html.fromHtml(htmlFromServer).toString()); } 

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