Установить текст 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
, лишенное любых тегов html и, следовательно, неформатировано.
Я знаю, что можно программно отформатировать текст с помощью
.setText(Html.fromHtml(somestring));
потому что я использую это в других частях моей программы, где он работает как ожидалось.
Для вызова этой функции мне нужен Activity
, но на данный момент мой макет - это просто более или менее статический вид в простом XML, и я бы предпочел оставить его таким образом, чтобы избавить меня от накладных расходов создав Activity
только для установки некоторого текста.
Я не замечаю ничего очевидного? Разве это вообще невозможно? Любая помощь или обходные пути приветствуются!
Edit: просто попробовал кое-что, и кажется, что форматирование HTML в xml имеет некоторые ограничения:
-
Теги
-
должны быть записаны в нижнем регистре
-
некоторые теги, которые упоминаются здесь, не работают, например. <br/>
(вместо этого можно использовать \n
)
Ответы
Ответ 1
На всякий случай, если кто-нибудь найдет это, есть более приятная альтернатива, которая не документирована (я споткнулся о ней после поиска часов и, наконец, нашел ее в списке ошибок для самого Android SDK). Вы CAN включаете необработанный 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)));
IMHO, на несколько порядков лучше работать с: -)
Ответ 2
В качестве верхнего ответа здесь говорится о некорректном (или, по крайней мере, слишком сложном), я считаю, что это должно быть обновлено, хотя вопрос довольно старый:
При использовании ресурсов String в Android вам просто нужно вызвать getString(...)
из кода Java или использовать android:text="@string/..."
в вашем XML-макете.
Даже если вы хотите использовать разметку HTML в своих строках, вам не нужно много менять:
Единственными символами, которые вам нужно избежать в ваших ресурсах String, являются:
- двойная кавычка:
"
становится \"
- одинарная кавычка:
'
становится \'
- ampersand:
&
становится &
или &
Это означает, что вы можете добавить 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(...)
.
Все это описано в документах.
Edit:
Нет разницы между getText(...)
с невыбранным HTML (как я предложил) или CDATA
разделами и Html.fromHtml(...)
.
См. следующий рисунок для сравнения:
![enter image description here]()
Ответ 3
Сбросьте свои HTML-теги...
<resources>
<string name="somestring">
<B>Title</B><BR/>
Content
</string>
</resources>
Ответ 4
Android не имеет спецификации для указания типа строки ресурса (например, text/plain или text/html). Однако есть обходное решение, которое позволит разработчику указать это в XML файле.
- Определите настраиваемый атрибут, чтобы указать, что атрибут android: text является html.
- Используйте подклассу 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();
}
}
}
Ответ 5
Последнее обновление:
Html.fromHtml(string);//устарел после версий Android N.
Следующий код предоставляет поддержку android 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));
}
Ответ 6
У меня есть другой случай, когда у меня нет возможности поместить CDATA в xml, поскольку я получаю строку HTML с сервера.
Вот что я получаю с сервера:
<p>The quick brown <br />
fox jumps <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());
}
Надеюсь, это поможет!
Линх
Ответ 7
String termsOfCondition="<font color=#cc0029>Terms of Use </font>";
String commma="<font color=#000000>, </font>";
String privacyPolicy="<font color=#cc0029>Privacy Policy </font>";
Spanned text=Html.fromHtml("I am of legal age and I have read, understood, agreed and accepted the "+termsOfCondition+commma+privacyPolicy);
secondCheckBox.setText(text);