Установить 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
а)
6 ответов
на всякий случай, если кто-нибудь найдет это, есть более приятная альтернатива, которая не документирована (я споткнулся об нее после поиска в течение нескольких часов и, наконец, нашел ее в списке ошибок для самого Android SDK). Вы CAN включить необработанный HTML в строки.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)));
ИМХО, это на несколько порядков приятнее работать с :-)
в качестве верхнего ответа здесь предлагается что-то неправильное (или, по крайней мере, слишком сложно), я чувствую, что это должно быть обновлено, хотя вопрос довольно старый:
при использовании строковых ресурсов в Android, вам просто нужно позвонить getString(...)
из кода Java или использовать android:text="@string/..."
в вашем макете XML.
даже если вы хотите использовать разметку HTML в своих строках, вам не нужно много менять:
единственные символы, которые вам нужно escape в ваших строковых ресурсах:
- двойные кавычки:
"
становится\"
- одинарные кавычки:
'
становится\'
- амперсанд:
&
становится&
или&
это означает, что вы можете добавить вашу разметка 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(...)
если ты ... --60-->сделал кодируйте свои специальные символы в разметке HTML. Используйте его с getString(...)
затем. Это может быть необходимо, если вы хотите передать строку String.format(...)
.
это все описано в документах как хорошо.
Edit:
нет никакой разницы между getText(...)
С unescaped HTML (как я предложил) или CDATA
разделы и Html.fromHtml(...)
.
см. следующий график для a сравнение:
побег HTML-тегов ...
<resources>
<string name="somestring">
<B>Title</B><BR/>
Content
</string>
</resources>
Android не имеет спецификации для указания типа строки ресурса (например, text/plain или text/html). Однако существует обходной путь, который позволит разработчику указать это в XML-файле.
- определите пользовательский атрибут, чтобы указать, что атрибут android: text является html.
- используйте подкласс TextView.
как только вы определите их, вы можете выразить себя с помощью HTML в xml-файлах без необходимости вызова помощью setText(формат HTML.fromHtml(...)) снова. Я довольно удивлен, что этот подход не является частью API.
это решение работает в той степени, что Android studio simulator будет отображать текст в формате HTML.
res / значения / строки.xml (строковый ресурс как HTML)
<resources>
<string name="app_name">TextViewEx</string>
<string name="string_with_html"><![CDATA[
<em>Hello</em> <strong>World</strong>!
]]></string>
</resources>
макет.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 версий..
следующий код дает поддержку 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));
}
у меня есть другой случай, когда у меня нет возможности поместить 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());
}
надеюсь, что это помогает!
Линх