Android中的TextViews,EditTexts和Buttons上的小型大写字母

时间:2013-04-12 04:58:46

标签: android text typography

我能做些什么来让文字看起来像小盘/大写?如下所述:http://en.wikipedia.org/wiki/Small_caps。我使用了转换器,但缺少一些字符。

6 个答案:

答案 0 :(得分:18)

编辑2015-08-02 :从API 21(Lollipop)开始,您只需添加:

android:fontFeatureSettings="smcp"

到XML中的TextView声明,或者在运行时调用:

textView.setFontFeatureSettings("smcp");

当然,这仅适用于API 21及更高版本,因此您仍需手动处理旧解决方案,直到您只支持棒棒糖及以上版本。


作为一名排版爱好者,这似乎是一个非常好的问题。我今天要学习更多关于Unicode的知识,以及你的问题的答案。 :)

首先,您需要一个包含“实际”小型大写字符的字体。我假设你知道,因为你问,但通常大多数专业字体包括这些。遗憾的是,大多数专业字体未获得分发许可,因此您可能无法在应用程序中使用它们。无论如何,如果你找到一个(我在这里使用Chaparral Pro作为例子),这就是你如何获得小型上限。

this answer我发现小型大写字母(对于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
};

然后添加了一个帮助方法,将输入字符串转换为小写字母已被Small Caps等效字母替换的字符串:

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));

我得到了以下结果:

Example of Small Caps

答案 1 :(得分:6)

抱怨拖出一个很老的问题。

我喜欢@ kcoppock的方法,但遗憾的是我使用的字体缺少小字符。我怀疑很多人会发现自己处于这种状况。

这激发了我写一个小的util方法,它将采用一个混合大小写的字符串(例如Small Caps)并创建一个格式化的spannable字符串看起来像 Sᴍᴀʟʟ Cᴀᴘs但是仅使用标准AZ字符。

  • 适用于任何具有A-Z字符的字体 - 无需特殊要求
  • 它很容易在TextView(或任何其他基于文本的视图)中使用
  • 它不需要任何HTML
  • 不需要对原始字符串进行任何编辑

我在这里提出了代码:https://gist.github.com/markormesher/3e912622d339af01d24e

答案 2 :(得分:0)

Is it possible to have multiple styles inside a TextView?

找到替代方案

基本上你可以使用html标签格式化字符的大小并给出一个小的大写效果....

答案 3 :(得分:0)

只需调用此getSmallCaps(文本)函数:

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;
}

答案 4 :(得分:0)

这不是我的代码,但它完美无缺。

 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);

答案 5 :(得分:-2)

XML中的

编辑文本有属性:android:capitalize =“”