String strResult = String.format(strFormat, 'Tim');
((TextView)findViewById(R.layout.some_label)).setText (strResult);
Styled Text
If you want really rich text, you should have raw resources containing HTML, then pour those into a WebKit widget. However, for light HTML formatting, using <b>, <i>, and <u>, you can just use a string resource:
<resources>
<string name='b'>This has <b>bold</b> in it.</string>
<string name='i'>Whereas this has <i>italics</i>!</string>
</resources>
You can access these the same as with plain strings, with the exception that the result of the getString()
call is really an object supporting the android.text.Spanned
interface:
((TextView)findViewById(R.layout.another_label))
.setText(getString(R.string.laughs));
Styled Formats
Where styled text gets tricky is with styled string formats, as String.format()
works on String
objects, not Spanned
objects with formatting instructions. If you really want to have styled string formats, here is the workaround:
1. Entity-escape the angle brackets in the string resource (e.g., this is <b>%1$s</b>
).
2. Retrieve the string resource as normal, though it will not be styled at this point (e.g., getString(R.string.funky_format)
).
3. Generate the format results, being sure to escape any string values you substitute in, in case they contain angle brackets or ampersands.
String.format(getString (R.string.funky_format),
TextUtils.htmlEncode(strName));
4. Convert the entity-escaped HTML into a Spanned
object via Html.fromHtml()
.
someTextView.setText(Html
.fromHtml(resultFromStringFormat));
To see this in action, let’s look at the Resources/Strings
demo, which can be found in the Source Code area of http://apress.com. Here is the layout file:
<?xml version='1.0' encoding='utf-8'?>
<LinearLayout xmlns:android='http://schemas.android.com/apk/res/android'
android:orientation='vertical'
android:layout_width='fill_parent'
android:layout_height='fill_parent'
>
<LinearLayout xmlns:android='http://schemas.android.com/apk/res/android'
android:orientation='horizontal'
android:layout_width='fill_parent'
android:layout_height='wrap_content'
>
<Button android:id='@+id/format'
android:layout_width='wrap_content'
android:layout_height='wrap_content'
android:text='@string/btn_name'
/>
<EditText android:id='@+id/name'
android:layout_width='fill_parent'
android:layout_height='wrap_content'
/>
</LinearLayout>
<TextView android:id='@+id/result'
android:layout_width='fill_parent'
android:layout_height='wrap_content'
/>
</LinearLayout>
As you can see, it is just a button, a field, and a label. The intent is for somebody to enter their name in the field, then click the button to cause the label to be updated with a formatted message containing their name.
The Button in the layout file references a string resource (@string/btn_name
), so we need a string resource file (res/values/strings.xml
):
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name='app_name'>StringsDemo</string>
<string name='btn_name'>Name:</string>
<string name='funky_format'>My name is <b> %1$s</b></string>
</resources>
The app_name
resource is automatically created by the activityCreator
script. The btn_name
string is the caption of the Button
, while our styled string format is in funky_format
.
Finally, to hook all this together, we need a pinch of Java:
package com.commonsware.android.resources;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.text.Html;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class StringsDemo extends Activity {
EditText name;
TextView result;