可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have some fixed strings inside my strings.xml
, something like:
<resources>
<string name=\"somestring\">
<B>Title</B><BR/>
Content
</string>
</resources>
and in my layout I\'ve got a TextView
which I\'d like to fill with the html-formatted string.
<TextView android:id=\"@+id/formattedtext\"
android:layout_width=\"fill_parent\"
android:layout_height=\"wrap_content\"
android:text=\"@string/htmlstring\"/>
if I do this, the content of formattedtext
is just the content of somestring
stripped of any html tags and thus unformatted.
I know that it is possible to set the formatted text programmatically with
.setText(Html.fromHtml(somestring));
because I use this in other parts of my program where it is working as expected.
To call this function I need an Activity
, but at the moment my layout is just a simple more or less static view in plain XML and I\'d prefer to leave it that way, to save me from the overhead of creating an Activity
just to set some text.
Am I overlooking something obvious? Is it not possible at all? Any help or workarounds welcome!
Edit: Just tried some things and it seems that HTML formatting in xml has some restraints:
tags must be written lowercase
some tags which are mentioned here do not work, e.g. <br/>
(it\'s possible to use \\n
instead)
回答1:
Just in case anybody finds this, there\'s a nicer alternative that\'s not documented (I tripped over it after searching for hours, and finally found it in the bug list for the Android SDK itself). You CAN include raw HTML in strings.xml, as long as you wrap it in
<![CDATA[ ...raw html... ]]>
Example:
<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>
Then, in your code:
TextView foo = (TextView)findViewById(R.id.foo);
foo.setText(Html.fromHtml(getString(R.string.nice_html)));
IMHO, this is several orders of magnitude nicer to work with :-)
回答2:
As the top answer here is suggesting something wrong (or at least too complicated), I feel this should be updated, although the question is quite old:
When using String resources in Android, you just have to call getString(...)
from Java code or use android:text=\"@string/...\"
in your layout XML.
Even if you want to use HTML markup in your Strings, you don\'t have to change a lot:
The only characters that you need to escape in your String resources are:
- double quotation mark:
\"
becomes \\\"
- single quotation mark:
\'
becomes \\\'
- ampersand:
&
becomes &
or &
That means you can add your HTML markup without escaping the tags:
<string name=\"my_string\"><b>Hello World!</b> This is an example.</string>
However, to be sure, you should only use <b>
, <i>
and <u>
as they are listed in the documentation.
If you want to use your HTML strings from XML, just keep on using android:text=\"@string/...\"
, it will work fine.
The only difference is that, if you want to use your HTML strings from Java code, you have to use getText(...)
instead of getString(...)
now, as the former keeps the style and the latter will just strip it off.
It\'s as easy as that. No CDATA, no Html.fromHtml(...)
.
You will only need Html.fromHtml(...)
if you did encode your special characters in HTML markup. Use it with getString(...)
then. This can be necessary if you want to pass the String to String.format(...)
.
This is all described in the docs as well.
Edit:
There is no difference between getText(...)
with unescaped HTML (as I\'ve proposed) or CDATA
sections and Html.fromHtml(...)
.
See the following graphic for a comparison:
回答3:
Escape your HTML tags ...
<resources>
<string name=\"somestring\">
<B>Title</B><BR/>
Content
</string>
</resources>
回答4:
Android does not have a specification to indicate the type of resource string (e.g. text/plain or text/html). There is a workaround, however, that will allow the developer to specify this within the XML file.
- Define a custom attribute to specify that the android:text attribute is html.
- Use a subclassed TextView.
Once you define these, you can express yourself with HTML in xml files without ever having to call setText(Html.fromHtml(...)) again. I\'m rather surprised that this approach is not part of the API.
This solution works to the degree that the Android studio simulator will display the text as rendered HTML.
res/values/strings.xml (the string resource as HTML)
<resources>
<string name=\"app_name\">TextViewEx</string>
<string name=\"string_with_html\"><![CDATA[
<em>Hello</em> <strong>World</strong>!
]]></string>
</resources>
layout.xml (only the relevant parts)
Declare the custom attribute namespace, and add the android_ex:isHtml attribute. Also use the subclass of 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 (define the custom attributes for the subclass)
<resources>
<declare-styleable name=\"TextViewEx\">
<attr name=\"isHtml\" format=\"boolean\"/>
<attr name=\"android:text\" />
</declare-styleable>
</resources>
TextViewEx.java (the subclass of 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:
Latest update:
Html.fromHtml(string);//deprecated after Android N versions..
Following code give support to android N and above versions...
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:
I have another case when I have no chance to put CDATA into the xml as I receive the string HTML from a server.
Here is what I get from a server:
<p>The quick brown <br />
fox jumps <br />
over the lazy dog<br />
</p>
It seems to be more complicated but the solution is much simpler.
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());
}
Hope it helps!
Linh