关闭

从零学Android(九)、Android资源类型之String资源

标签: android ResoucesandroidStringSpannableString Style
188人阅读 评论(0) 收藏 举报
分类:

String资源比较常用,而且规范也比较多,这里稍作记录。其它资源使用都比较简单,就不记录了。

概述

字符串资源是给应用程序提供可选文本样式和格式的文本字符串。所有的字符串资源都具有使用一些样式和格式化参数的能力。它可以分为以下三种类别:

一、单一字符串String

提供单一的字符串资源。

二、字符串数组String Array

提供一个字符串数据资源。

三、区分单复数的数量字符串Quantity Strings (Plurals)

提供在单复数不同情况下的不同字符串资源。都说这个在开发中貌似没啥用,就不记录了,有兴趣的大致了解一下就行了。


1.单一字符串String

单一的字符串资源可以被应用程序代码或其它诸如布局资源XML文件引用。由于单一字符串资源的ID是name属性名,而不是XML文件的名称,所以它可以喝其它一些简单资源组合到一个XML文件中,放置到一个<resources>标签下。

文件位置:res/values/filename.xml

其中的文件名是任意的,<string>元素的name属性取值则为资源ID。

编译后的数据类型:String

资源的引用:

在java文件代码中:R.string.string_name

在XML文件中:@string/string_name

语法:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string
        name="string_name"
        >text_string</string>
</resources>
标签元素说明:

<resources>标签:这个属性是必须。而且它必须作为文档的根元素。

<string>标签:可以包含样式的字符串。注意:如果字符串内容包含单引号或者双引号,必须做转义。

name属性:字符串的名称。将作为资源ID。

例子:编写res/values/strings.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello!</string>
</resources>
在XML中引用:
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello" />

在java代码中使用:

String string = getString(R.string.hello);
我们也能通过使用Context的getString(int)或者getText(int)方法去获取字符串资源。getText(int)方法会获取到一个富文本样式的字符串。

2.字符串数组String Array

定义了给应用程序代码使用的字符串数组资源。它和单一字符串资源一样,使用name属性作为ID,可以和其它简单资源组合在一个XML文件中。

文件位置:res/values/filename.xml

其中的文件名称任意。而<string-array>元素的name属性将作为资源ID使用。

编译后的资源类型:字符串数组-String[]

资源的引用:只能在java代码中引用:R.array.string_array_name

语法:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array
        name="string_array_name">
        <item
            >text_string</item>
    </string-array>
</resources>
标签元素说明:

<resources>标签:这个属性是必须。而且它必须作为文档的根元素。

<string-array>标签:定义一个字符串数组,可以包含多个<item>元素标签。

name属性:字符串数组的名称。将作为资源ID。

<item>标签:可以包含样式的字符串资源,它的值可以是引用自另外一个字符串资源。必须作为<string-array>标签的子元素。同样,内容总有单双引号时要做转义处理。

例子:编写res/values/strings.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="planets_array">
        <item>Mercury</item>
        <item>Venus</item>
        <item>Earth</item>
        <item>Mars</item>
    </string-array>
</resources>
在Java代码中的使用:
Resources res = getResources();
String[] planets = res.getStringArray(R.array.planets_array);


3.样式和格式化

3.1 转义单引号和双引号

如果在字符串内容中包含一个单引号(‘),我们必须使用反斜线去对它进行转义(\')或者使用双引号("")将整个内容包裹起来。比如说:

<string name="good_example">This\'ll work</string>
<string name="good_example_2">"This'll also work"</string>
<string name="bad_example">This doesn't work</string>
    <!-- Causes a compile error -->

如果在字符串内容中包含双引号(”“)。我们就只能去使用转义字符了(\")。
<string name="good_example">This is a \"good string\".</string>
<string name="bad_example">This is a "bad string".</string>
    <!-- Quotes are stripped; displays as: This is a bad string. -->
<string name="bad_example_2">'This is another "bad string".'</string>
    <!-- Causes a compile error -->
3.2 格式化字符串

我们可以通过使用String.format(String, Object...)将我们的格式化参数插入到字符串资源中。如下的字符串资源:

<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
在上面这个字符串资源中,存在两个格式化参数:%1$s代表一个字符串类型参数,%2$d则代表一个十进制数。所以我们可以在代码中这样去格式化它:
Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);

3.3 包含HTML标签的样式

我们可以在我们的字符串资源中添加HTML标签。比如:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="welcome">Welcome to <b>Android</b>!</string>
</resources>
支持的HTML标签包含:

【1】<b>用来加粗

【2】<i> 用来表示斜体字

【3】<u> 用来添加下划线

有时候,我们可能需要给一些格式化的字符串资源添加样式。一般来说,样式不会对格式化资源起作用,因为String.format(String, Object...)方法会清除掉格式化字符串所有的样式信息。这个时候,我们需要将HTML标签进行一个转义操作(即使用对应的字符实体),然后再在格式化操作完成后,调用fromHtml(String)来获取字符串资源。比如说:

1.使用HTML字符实体保存我们的样式字符串:

<resources>
  <string name="welcome_messages">Hello, %1$s! You have &lt;b>%2$d new messages</b>.</string></resources>
在这个格式化字符串中,添加有一个<b>标签,注意其中的左括号使用了转义字符实体,即&lt;符号。

2.正常格式化字符串资源。然后调用fromHtml(String)方法转换HTML文本:

Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
CharSequence styledText = Html.fromHtml(text);
由于fromHtml(String)方法会格式化所有的HTML实体,所以我们需要使用htmlEncode(String)方法确认在进行格式化的过程中,那些可能存在的HTML字符都被转义了。所以,上面的代码应该修改如下:
String escapedUsername = TextUtil.htmlEncode(username);

Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), escapedUsername, mailCount);
CharSequence styledText = Html.fromHtml(text);


3.4 Spannables的样式

Spannable是支持使用诸如颜色和字体权重(font weight)等字体属性样式的文本对象。我们可以通过SpannableStringBuilder去创建我们的文本对象,然后使用android.text.style包下的样式应用到文本对象中。

我们可以使用下面这几个帮助方法去创建我们的文本对象:

/**
 * Returns a CharSequence that concatenates the specified array of CharSequence
 * objects and then applies a list of zero or more tags to the entire range.
 *
 * @param content an array of character sequences to apply a style to
 * @param tags the styled span objects to apply to the content
 *        such as android.text.style.StyleSpan
 *
 */
private static CharSequence apply(CharSequence[] content, Object... tags) {
    SpannableStringBuilder text = new SpannableStringBuilder();
    openTags(text, tags);
    for (CharSequence item : content) {
        text.append(item);
    }
    closeTags(text, tags);
    return text;
}

/**
 * Iterates over an array of tags and applies them to the beginning of the specified
 * Spannable object so that future text appended to the text will have the styling
 * applied to it. Do not call this method directly.
 */
private static void openTags(Spannable text, Object[] tags) {
    for (Object tag : tags) {
        text.setSpan(tag, 0, 0, Spannable.SPAN_MARK_MARK);
    }
}

/**
 * "Closes" the specified tags on a Spannable by updating the spans to be
 * endpoint-exclusive so that future text appended to the end will not take
 * on the same styling. Do not call this method directly.
 */
private static void closeTags(Spannable text, Object[] tags) {
    int len = text.length();
    for (Object tag : tags) {
        if (len > 0) {
            text.setSpan(tag, 0, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        } else {
            text.removeSpan(tag);
        }
    }
}
下面bold,italiccolor三个方法,演示了怎么通过调用上面的帮助方法去使用android.text.style包下的样式:
/**
 * Returns a CharSequence that applies boldface to the concatenation
 * of the specified CharSequence objects.
 */
public static CharSequence bold(CharSequence... content) {
    return apply(content, new StyleSpan(Typeface.BOLD));
}

/**
 * Returns a CharSequence that applies italics to the concatenation
 * of the specified CharSequence objects.
 */
public static CharSequence italic(CharSequence... content) {
    return apply(content, new StyleSpan(Typeface.ITALIC));
}

/**
 * Returns a CharSequence that applies a foreground color to the
 * concatenation of the specified CharSequence objects.
 */
public static CharSequence color(int color, CharSequence... content) {
    return apply(content, new ForegroundColorSpan(color));
}
下面是一个应用样式的例子:
// Create an italic "hello, " a red "world",
// and bold the entire sequence.
CharSequence text = bold(italic(res.getString(R.string.hello)),
    color(Color.RED, res.getString(R.string.world)));

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:5018次
    • 积分:194
    • 等级:
    • 排名:千里之外
    • 原创:15篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章存档