Phrase 是一个用来替代 Android 中字符串格式化功能的小型类库。解决了在实际开发中遇到的几个问题。这些问题如下:
假如有这么一个 字符串定义:
Java
Hello %1$s, today\'s cook yielded %2$d %3$s.
1
2
3
Hello%1$s,today\'scookyielded%2$d%3$s.
使用 Resources 的 getString(…) 函数可以很方便的格式化其内容:
Java
String name = "Walter";
int yield = 50;
String unit = "pounds";
String greeting = context.getString(R.string.greeting, name, yield, unit);
1
2
3
4
Stringname="Walter";
intyield=50;
Stringunit="pounds";
Stringgreeting=context.getString(R.string.greeting,name,yield,unit);
但是这里的 %1$s 和 %2$d 是非常程序话的,不查看文本内容根本无法知道其代表的含义,另外 ,多个参数的顺序也非常重要,如果搞错了,显示的内容就错了。
另外 getString(…) 函数还无法处理 HTML 格式化标签。例如 文字加粗、斜体等。 该函数会把这些基本标签给过滤掉。
Phrase
Phrase 使用 命名参数的解决方式,例如:
Java
Hello {name}, today\'s cook yielded {yield} {unit}.
1
2
3
Hello{name},today\'scookyielded{yield}{unit}.
为了减少翻译这些字符串出错的可能性,所以规则制定的比较粗暴:
使用大括号来环绕一个参数,文本中的大括号需要使用两个大括号来表示
参数的名字需要依靠小写字母开始,后面只能跟小写字母和下划线
然后使用如下方式来格式化该字符串:
Java
// 这里 put(...) 函数的调用顺序是无关紧要的
CharSequence greeting = Phrase.from(context, R.string.greeting)
.put("unit", unit)
.put("name", name)
.put("yield", yield)
.format();
1
2
3
4
5
6
// 这里 put(...) 函数的调用顺序是无关紧要的
CharSequencegreeting=Phrase.from(context,R.string.greeting)
.put("unit",unit)
.put("name",name)
.put("yield",yield)
.format();
注意, Phrase 返回的是一个 CharSequence 而不是 String, 这样可以支持基本的格式化字符串。例如:
Java
Did you learn nothing from my {class_type} class?
1
2
3
4
Didyoulearnnothingfrommy{class_type}class?
另外,为了避免文本显示错误,当遇到如下问题的时候, Phrase 就即刻抛出错误:
命名参数不规范或者缺少配对的大括号
put(...) 函数参数不能为 null
put(...) 的 key 在格式化字符串中不存在
调用 format() 的时候还有 参数 没赋值的情况
paraphrase
paraphrase虽然使用 Phrase 来格式化字符串,减少了翻译字符和格式化字符串出错的可能性,但是使用起来还是有点麻烦,而 paraphrase 这个 Gradle 插件使 Phrase 的使用更加方便。
例如:
Java
Hello, {other_name}! My name is {my_name}.
1
Hello,{other_name}!Mynameis{my_name}.
使用 Gradle 编译后可以这样用 Phrase:
Java
CharSequence greeting = Phrase.greeting()
.other_name("GitHub user")
.my_name("Jake Wharton")
.build(this);
1
2
3
4
CharSequencegreeting=Phrase.greeting()
.other_name("GitHub user")
.my_name("Jake Wharton")
.build(this);
如果你在翻译的时候,错误的修改了字符串:
Java
Hello! My name is {my_name}.
1
Hello!Mynameis{my_name}.
Java
Example.java:34: error: cannot find symbol
.other_name("GitHub user")
^
symbol: method other_name(String)
location: class Phrase_greeting
1
2
3
4
5
6
Example.java:34:error:cannotfindsymbol
.other_name("GitHub user")
^
symbol:methodother_name(String)
location:classPhrase_greeting
现在编译项目的时候就会报错,而不是在运行应用的时候 Crash。
在项目中的build.gradle 配置文件中添加如下内容来使用 paraphrase:
Java
buildscript {
repositories {
mavenCentral()
maven url: 'http://oss.sonatype.org/content/repositories/snapshots/'
}
dependencies {
classpath 'com.android.tools.build:gradle:0.8.+'
classpath 'com.jakewharton.paraphrase:paraphrase:1.0.0-SNAPSHOT'
}
}
apply plugin: 'android'
apply plugin: 'paraphrase'
1
2
3
4
5
6
7
8
9
10
11
12
13
buildscript{
repositories{
mavenCentral()
mavenurl:'http://oss.sonatype.org/content/repositories/snapshots/'
}
dependencies{
classpath'com.android.tools.build:gradle:0.8.+'
classpath'com.jakewharton.paraphrase:paraphrase:1.0.0-SNAPSHOT'
}
}
applyplugin:'android'
applyplugin:'paraphrase'