String resource
Android应用提供了三种类型的资源:
String -- xml resource 单一字符串
String Array -- xml resource 数组字符串
Quantity String -- xml resource 数量字符串:
简单来说就是不同语言的语法对数量的表示不同如:在英语中数量1是个特别的情况,当写一本书的时候是“1 book” 但是其他数量的书时是“n books” 这里有单数和复数的区别而中文中没有这样的区别所以Android提供了这样的复数支持,现在Android中支持的数量字符串有 zero,one,two,few,many,other。根据语言的语法不同会有更精细的区别。
字符串创建及使用
要引用字符串资源首先要在Android项目中创建xml文件改文件地点在res/values/filename.xml你可以为它起一个随意的名字默认一般为strings.xml。
在res/values/目录下右单机依次---New->XML->values xml 然后创建一个名字为filestring字符串资源的文件,该文件默认只有标签,标签是必须的并且是整个xml的根节点。现在可以在该文件中创建你想要编写的字符串资源了使用下面语法来编写你的字符串信息。
单一字符串
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string
name="string_name"
>text_string</string>
</resources>
在java代码中使用:R.string.string_name
val string: String = getString(R.string.string_name)
在xml 代码中使用:@string/string_name
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/string_name" />
数组字符串
<?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代码中使用:R.array.planets_array
val array: Array = resources.getStringArray(R.array.planets_array)
在xml 代码中使用:@[package:]array/planets_array
注:xml中一些支持使用数组字符串的控件才可以使用如Spinner中的entries
< Spinner
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:entries ="@array/string_array_name" />
数量字符串
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals
name="plural_name">
<item
quantity=["zero" | "one" | "two" | "few" | "many" | "other"]
>text_string</item>
</plurals>
</resources>
具体定义如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="numberOfSongsAvailable">
<item quantity="one">%d song found.</item>
<item quantity="other">%d songs found.</item>
</plurals>
</resources>
在代码中使用
val count = getNumberOfSongsAvailable()
val songsFound = resources.getQuantityString(R.plurals.numberOfSongsAvailable, count, count)
当手机环境在英文的情况下,count数值为1的时候则songsFound值为 1 song found 当数值>1的时候则它的值为 >1值 songs found (注意:数量字符串需要根据手机系统当前语言才可生效)
字符串格式化
如果需要一些动态添加的字符,这里就需要字符串格式化,其支持的类型有:
%s 字符串(string)
%c 字符 (char)
%b 布尔值类型 (boolean)
%d 十进制整型 (12)
%x 十六进制整型(f0)
%f 十进制浮点 (1.0)
%0nd n位数补零 例如(%05d,77)这值为 00077 这里代表一个5位数的数字,位数不足则向左补0
我们一般常用的是 %s,%d下面例子展示了如何使用字符串格式化:
在xml中声明:
单数声明
<string name="welcome_messages">Hello, %s! </string>
在代码中使用 调用resource.getString(int,Object...)
val username = "Android"
var text = getString(R.string.welcome_messages, username)
复数声明
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
val username = "Android"
val messageCount =12
var text = getString(R.string.welcome_messages, username, messageCount)
Android中的Html样式
在Android中可以使用Html进行标记,如下面的例子
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="welcome">Welcome to <b>Android</b>!</string>
</resources>
这样就可以显示html相关的样式,Android中支持的Html样式有以下几种:
Bold: <b>, <em> 粗体
Italic: <i>, <cite>, <dfn> 斜体
25% larger text: <big> 缩放变大百分之二十五
20% smaller text: <small> 缩放变小百分之二十五
Setting font properties: <font face=”font_family“ color=”hex_color”>. 设置字体以及颜色 (可能支持的字体有 **monospace**, **serif**, **sans_serif**.)
Setting a monospace font family: <tt>
Strikethrough: <s>, <strike>, <del>删除线
Underline: <u> 下划线
Superscript: <sup> 上标
Subscript: <sub> 下标
Bullet points: <ul>, <li> 要点
Line breaks: <br> 换行符
Division: <div> 分隔符
CSS style: <span style=”color|background_color|text-decoration”>
Paragraphs: <p dir=”rtl | ltr” style=”…”>
Html样式的使用,正如上面的例子我们可以想平常那样调用textview.setText(resource)来显示一个字符串,但这不会应用我们写的html标签样式,因为我们调用getString(int,object...),String.format(String,Object...)方法时会从字符串中删除所有的样式(style)信息,所以我们要使用 Html.fromHtml(String)方法如:
val text = resource.getString(R.string.welcome)
val html:Spanned = Html.fromHtml(text, FROM_HTML_MODE_LEGACY)
textview.text=html
但是这样还是不能显示html样式因为在xml中<是HTML转义字符,应该使用<;符号代替,下面是完整的例子
<resources>
<string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string>
</resources>
val text: String = getString(R.string.welcome_messages, username, mailCount)
val styledText: Spanned = Html.fromHtml(text, FROM_HTML_MODE_LEGACY)
textview.text = styledText
如果说你格式化的字符串中包含"<","&"字符时,你就必须先把这些字符转义然后在传入到Html.fromHtml中使用,才可以得到预期的样式例如:
val username = "Android<"
val escaped = TextUtils.htmlEncode(username)
val text = getString(R.string.welcome_messages, username, mailCount)
val spanned = Html.fromHtml(text) --- 输出 ---**Hello, Android<!**...
转义字符
在xml/HTML中一些特殊字符有特别的含义不可以直接使用,这时我们就应该使用他们的转义序列才可以使用他们,通常Android有转义字符的显示形式有两种,Android中比较常用的转义字符有如下:
& &
< <
> >
" "
(空格)
© ©️ (版权符号)
® ®️ (注册符号)
@ \@ 当@在xml中一个字符串为首字母时需要转义
新行 \n
锁进 \t
U+XXXX Unicode character \uXXXX
使用 spannable 改变字符串样式
你可以使用Spannable来改变字符串样式,例如更改字符串的文字颜色,字体大小。在Androidx中你可以很轻松的构建一个你想要的样式使用SpannableStringBuilder的扩展方法来构建。在androidx.core.text包下,请看下面的例子
val spn = androidx.core.text.buildSpannedString{
append("Hello")
bold {
append("World!")
italic {
append("Hi")
color(Color.RED){
append("Android")
}
}
}
}
这样你就可以构建一个以World!为粗体,Hi为斜体,Android颜色为红的字符串,当然还有更多方法请参考Google官方文档。
使用xml中的注解(annotations)来构建复杂的样式
你可以在strings.xml中使用标签来自定义一个复杂的字符串样式,下面的形式为的使用方式:
<string name="title">Best practices for <annotation font="title_emphasis">text</annotation> on Android</string>
这种方式是通过使用Android的Annotation类来完成,在标签中通过定义个key-value
的键值对如上面所示 key = font value = title_emphasis 然后通过在代码中获取字符串中定义的所有annotation标签 通过创建一个新的span 如下面代码
//引用Google文档例子
val titleText = getText(R.string.title) as SpannedString
val annotations = titleText.getSpans(0, titleText.length, Annotation::class.java)
val spannableString = SpannableString(titleText)
for (annotation in annotations) {
if (annotation.key == "font") {
val fontName = annotation.value
if (fontName == "title_emphasis") {
val typeface = getFontCompat(R.font.permanent_marker)
spannableString.setSpan(CustomTypefaceSpan(typeface),
titleText.getSpanStart(annotation),
titleText.getSpanEnd(annotation),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}
}
// now, the spannableString contains both the annotation spans and the CustomTypefaceSpan
styledText.text = spannableString
xml字符串属性
xliff 属性
xliff属性的全称为xml localzation interchanage file format 即:xml本地化数据交换格式,用来标记不翻译的部分 例如:
<string name="local">
<xliff:g id ="loc" example="introduce">%1$s</xliff:g>
</string>
用这种标记的字符串 在翻译过程不会本更改
其中 id 为属性命名可以随意更改,example为属性用途可以忽略
xliff有三种格式:%n$ms(字符串) %n$md(整型) %n$mf(浮点型) 其中ms,md 中m代表前方可以放置几个空格,mf中m代表可以保留多少位小数 <默认可以不填写>例如:
<string name="local">
<xliff:g id ="loc" example="introduce">%1$2.2f</xliff:g>
</string>
val s = getString(R.string.local,5.5)
//m=2.2表示输出格式为00.00
//m=1.1表示输出0.0
//输出为5.50