Frage

Is there something I can do to make the text look in small caps/capital? As described here: http://en.wikipedia.org/wiki/Small_caps. I used a converter but some characters are missing.

War es hilfreich?

Lösung

EDIT 2015-08-02: As of API 21 (Lollipop) you can simply add:

android:fontFeatureSettings="smcp"

to your TextView declaration in XML, or at runtime, invoke:

textView.setFontFeatureSettings("smcp");

Of course, this only works for API 21 and up, so you'd still have to handle the old solution manually until you are only supporting Lollipop and above.


Being a bit of a typography geek at heart, this seemed like a really good question. I got to learn some more about Unicode today, as well as an answer for your question. :)

First, you'll need to have a font that includes "actual" small-caps characters. I'm assuming you know that since you're asking, but typically most professional fonts include these. Unfortunately most professional fonts are not licensed for distribution, so you may not be able to use them in your application. Anyway, in the event that you do find one (I used Chaparral Pro as an example here), this is how you can get small caps.

From this answer I found that the small caps characters (for A-Z) are located starting at Unicode-UF761. So I built a mapping of these characters:

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

Then added a helper method to convert an input string to one whose lowercase letters have been replaced by their Small Caps equivalents:

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

Then just use that anywhere:

String regularCase = "The quick brown fox jumps over the lazy dog.";
textView.setText(getSmallCapsString(regularCase));

For which I got the following result:

Example of Small Caps

Andere Tipps

Apologies for dragging up a very old question.

I liked @kcoppock's approach to this, but unfortunately the font I'm using is missing the small-cap characters. I suspect many others will find themselves in this situation.

That inspired me to write a little util method that will take a mixed-case string (e.g. Small Caps) and create a formatted spannable string that looks like Sᴍᴀʟʟ Cᴀᴘs but only uses the standard A-Z characters.

  • It works with any font that has the A-Z characters - nothing special required
  • It is easily useable in a TextView (or any other text-based view, for that matter)
  • It doesn't require any HTML
  • It doesn't require any editing of your original strings

I've posed the code here: https://gist.github.com/markormesher/3e912622d339af01d24e

Found an alternative here Is it possible to have multiple styles inside a TextView?

Basically you can use html tags formatting the size of the characters and give a small caps effect....

Just call this getSmallCaps(text) function:

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

This is not my code but its works perfectly.

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

Example:

SpannableString setStringObj = getSmallCapsStringTwo("Object"); tvObj.setText(setStringObj);

in XML edit text has property :android:capitalize=""

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top