有没有什么方法可以让文本以小型大写字母的形式显示?如此描述:http://en.wikipedia.org/wiki/Small_caps。我使用了一个转换器,但有一些字符丢失了。
有没有什么方法可以让文本以小型大写字母的形式显示?如此描述:http://en.wikipedia.org/wiki/Small_caps。我使用了一个转换器,但有一些字符丢失了。
android:fontFeatureSettings="smcp"
在 XML 中添加 TextView
声明,或在运行时调用:
textView.setFontFeatureSettings("smcp");
当然,这仅适用于API 21及以上版本,因此您仍需要手动处理旧解决方案,直到只支持棒棒糖(Android 5.0)及以上版本。
作为一个内心有点儿字体极客的人,这个问题似乎很不错。今天我学到了更多关于Unicode的知识,并得到了你的问题的答案。:)
首先,您需要拥有一种包含“实际”小型大写字母字符的字体。我假设您知道这一点,但通常大多数专业字体都包含这些字符。不幸的是,大多数专业字体未经许可不得分发,因此您可能无法在应用程序中使用它们。无论如何,在您找到一种字体后,以下是如何获取小型大写字母的方法(我在这里以Chaparral Pro为例)。
从这个答案中,我发现小型大写字母字符(A-Z)的Unicode编码从UF761开始。因此,我构建了这些字符的映射:
private static char[] smallCaps = new char[]
{
'\uf761', //A
'\uf762',
'\uf763',
'\uf764',
'\uf765',
'\uf766',
'\uf767',
'\uf768',
'\uf769',
'\uf76A',
'\uf76B',
'\uf76C',
'\uf76D',
'\uf76E',
'\uf76F',
'\uf770',
'\uf771',
'\uf772',
'\uf773',
'\uf774',
'\uf775',
'\uf776',
'\uf777',
'\uf778',
'\uf779',
'\uf77A' //Z
};
然后添加了一个辅助方法,将输入的字符串转换为小写字母已被其小型大写字母等效替代的字符串:
private static String getSmallCapsString (String input) {
char[] chars = input.toCharArray();
for(int i = 0; i < chars.length; i++) {
if(chars[i] >= 'a' && chars[i] <= 'z') {
chars[i] = smallCaps[chars[i] - 'a'];
}
}
return String.valueOf(chars);
}
那么只需将其随处使用:
String regularCase = "The quick brown fox jumps over the lazy dog.";
textView.setText(getSmallCapsString(regularCase));
我得到了以下结果:
抱歉拿出一个非常老的问题。
我喜欢@kcoppock的方法,但不幸的是我正在使用的字体缺少小型大写字母。 我怀疑很多人会发现自己处于这种情况。
这启发我编写了一个小型实用程序方法,它将采用混合大小写字符串(例如Small Caps
)并创建一个格式化的可跨度字符串,看起来像Sᴍᴀʟʟ Cᴀᴘs
,但仅使用标准的A-Z字符。
A-Z
字符的任何字体-无需特殊要求我在这里发布了代码:https://gist.github.com/markormesher/3e912622d339af01d24e
只需调用此getSmallCaps(text)函数:
public SpannableStringBuilder getSmallCaps(String text) {
text = text.toUpperCase();
text = text.trim();
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
if (text.contains(" ")) {
String[] arr = text.split(" ");
for (int i = 0; i < arr.length; i++) {
spannableStringBuilder.append(getSpannableStringSmallCaps(arr[i]));
spannableStringBuilder.append(" ");
}
} else {
spannableStringBuilder=getSpannableStringSmallCaps(text);
}
return spannableStringBuilder;
}
public SpannableStringBuilder getSpannableStringSmallCaps(String text) {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(
text);
spannableStringBuilder.setSpan(new AbsoluteSizeSpan(36), 0, 1, 0);
spannableStringBuilder.setSpan(new StyleSpan(Typeface.BOLD), 0, 1, 0);
spannableStringBuilder.setSpan(new StyleSpan(Typeface.BOLD), 1,
text.length(), 0);
return spannableStringBuilder;
}
public SpannableString getSmallCapsString(String input) {
// values needed to record start/end points of blocks of lowercase letters
char[] chars = input.toCharArray();
int currentBlock = 0;
int[] blockStarts = new int[chars.length];
int[] blockEnds = new int[chars.length];
boolean blockOpen = false;
// record where blocks of lowercase letters start/end
for (int i = 0; i < chars.length; ++i) {
char c = chars[i];
if (c >= 'a' && c <= 'z') {
if (!blockOpen) {
blockOpen = true;
blockStarts[currentBlock] = i;
}
// replace with uppercase letters
chars[i] = (char) (c - 'a' + '\u0041');
} else {
if (blockOpen) {
blockOpen = false;
blockEnds[currentBlock] = i;
++currentBlock;
}
}
}
// add the string end, in case the last character is a lowercase letter
blockEnds[currentBlock] = chars.length;
// shrink the blocks found above
SpannableString output = new SpannableString(String.valueOf(chars));
for (int i = 0; i < Math.min(blockStarts.length, blockEnds.length); ++i) {
output.setSpan(new RelativeSizeSpan(0.8f), blockStarts[i], blockEnds[i], Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
return output;
}
例子:
SpannableString setStringObj = getSmallCapsStringTwo("Object"); tvObj.setText(setStringObj);
在XML中,编辑文本具有属性:android:capitalize=""