我在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的内容只是一些字符串的内容剥离任何html标签,因此未格式化。
我知道可以用编程方式设置格式化文本
.setText(Html.fromHtml(somestring));
因为我在程序的其他部分使用了这个,在那里它是正常工作的。
要调用这个函数,我需要一个Activity,但目前我的布局只是一个简单的或多或少静态的纯XML视图,我宁愿让它这样,以节省我创建一个活动的开销,只是设置一些文本。
我是不是忽略了一些显而易见的东西?难道根本不可能吗?欢迎任何帮助或解决办法!
编辑:刚刚尝试了一些东西,似乎HTML格式在xml有一些限制:
标签必须小写
这里提到的一些标签不起作用,例如<br/>(可以使用\n代替)
Android没有指定资源字符串的类型(例如text/plain或text/html)。但是,有一种变通方法允许开发人员在XML文件中指定这一点。
定义一个自定义属性,指定android:text属性为html。
使用子类化的TextView。
一旦你定义了这些,你就可以在xml文件中使用HTML来表达自己,而不必再次调用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>
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>
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();
}
}
}
因为上面的答案暗示了一些错误(或者至少太复杂了),我觉得这个问题应该更新,尽管这个问题相当老了:
当在Android中使用String资源时,你只需要从Java代码中调用getString(…)或在你的布局XML中使用Android:text="@string/…"
即使你想在你的字符串中使用HTML标记,你也不需要做很多改变:
在String资源中唯一需要转义的字符是:
双引号:“变成\”
单引号:“变成\”
&号:&变成&或者,
这意味着你可以添加你的HTML标记而不转义标签:
<string name="my_string"><b>Hello World!</b> This is an example.</string>
但是,为了确定,您应该只使用文档中列出的<b>, <i>和<u>。
如果你想使用你的HTML字符串从XML,只是继续使用android:text="@字符串/…",它会工作的很好。
唯一的区别是,如果您想从Java代码中使用HTML字符串,现在必须使用getText(…)而不是getString(…),因为前者保留了样式,而后者只会剥离它。
就这么简单。没有CDATA,没有Html.fromHtml(…)。
如果在HTML标记中编码特殊字符,则只需要使用HTML . fromhtml(…)。然后与getString(…)一起使用它。如果你想将String传递给String.format(…),这可能是必要的。
这些在文档中都有描述。
编辑:
getText(…)与未转义的HTML(如我所建议的)或CDATA部分与HTML . fromhtml(…)之间没有区别。
对比如下图所示: