从XML格式的html格式的字符串资源中设置TextView文本

时间:2010-07-13 07:51:11

标签: html android formatting textview

我的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,但目前我的布局只是一个简单的或多或少的静态视图,我希望保持这种方式,以节省我创建Activity只是设置一些文本的开销。

我忽略了一些明显的东西吗?它根本不可能吗?欢迎任何帮助或变通方法!

编辑:刚试了一些东西,似乎xml中的HTML格式有一些限制:

  • 标签必须写成小写

  • 提到的某些标签here不起作用,例如<br/>(可以使用\n代替)

7 个答案:

答案 0 :(得分:463)

万一有人发现这个,有一个更好的替代方案没有记录(我在搜索了几个小时之后绊倒了它,最后在Android SDK本身的bug列表中找到了它)。您 CAN 在strings.xml中包含原始HTML,只要您将其包装在

<![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)));
恕我直言,这可以使用几个数量级: - )

答案 1 :(得分:121)

由于这里的最佳答案是建议错误(或者至少过于复杂),我觉得应该更新,尽管问题已经很久了:

在Android中使用String资源时,您只需从Java代码中调用getString(...)或在布局XML中使用android:text="@string/..."

即使您想在字符串中使用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标记中的特殊字符进行编码,则只需Html.fromHtml(...)。然后将其与getString(...)一起使用。如果要将字符串传递给String.format(...)

,则可能需要这样做

这也是in the docs所描述的。

修改

getText(...)与非转义HTML(我提议)或CDATA部分和Html.fromHtml(...)之间没有区别。

请参阅下图以进行比较:

enter image description here

答案 2 :(得分:15)

转义HTML标记...

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

答案 3 :(得分:10)

Android没有指定资源字符串类型的规范(例如text / plain或text / html)。但是,有一种解决方法可以让开发人员在XML文件中指定它。

  1. 定义自定义属性以指定android:text属性为html。
  2. 使用子类TextView。
  3. 一旦定义了这些,就可以用xml文件中的HTML表达自己,而无需再次调用setText(Html.fromHtml(...))。我很惊讶这种方法不是API的一部分。

    此解决方案适用于Android工作室模拟器将文本显示为呈现HTML的程度。

    enter image description here

    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();
        }
    }
    }
    

答案 4 :(得分:9)

最新更新:

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));
}

答案 5 :(得分:3)

  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);

答案 6 :(得分:2)

我有另一种情况,当我从服务器收到字符串HTML时,我没有机会将CDATA放入xml。

以下是我从服务器获得的信息:

<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());

}

希望它有所帮助!