2013-04-12 13 views

risposta

17

EDIT 2015/08/02: A partire dal 21 API (Lollipop) si può semplicemente aggiungere:

android:fontFeatureSettings="smcp" 

al vostro TextView dichiarazione in XML, o in fase di esecuzione, richiamare:

textView.setFontFeatureSettings("smcp"); 

Naturalmente, questo funziona solo per API 21 e in alto, quindi dovresti ancora gestire manualmente la vecchia soluzione finché non supporti solo Lollipop e versioni successive.


Essendo un po 'geek tipografia al cuore, questa mi è sembrata una domanda davvero buona. Ho avuto modo di imparare un po 'di più su Unicode oggi, oltre che una risposta alla tua domanda. :)

Innanzitutto, è necessario disporre di un carattere che includa caratteri "reali" di maiuscoletto. Presumo che tu lo sappia da quando lo chiedi, ma in genere i font più professionali includono questi. Sfortunatamente molti font professionali non sono autorizzati per la distribuzione, quindi potresti non essere in grado di usarli nella tua applicazione. Ad ogni modo, nel caso in cui si trovi do trovarne uno (ho usato Chaparral Pro come esempio qui), questo è il modo in cui è possibile ottenere maiuscoletto.

Da this answer Ho trovato che i caratteri maiuscoletto (per A-Z) si trovano a partire da Unicode-UF761. Così ho costruito una mappatura di questi personaggi:

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

Poi ha aggiunto un metodo di supporto per convertire una stringa di input a uno le cui lettere minuscole sono stati sostituiti dai loro MAIUSCOLETTO equivalenti:

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

Poi basta usare che ovunque:

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

Per cui ho ottenuto il seguente risultato:

Example of Small Caps

+0

Grazie per l'ottima risposta! L'ho provato ma mi ha dato caratteri cinesi? – naz

+0

Sì, dovrai usare un carattere che include caratteri maiuscoletto per far funzionare tutto questo. Tipicamente un font OpenType. – kcoppock

+0

come si visualizza il codice uf000? Se ho un font quale strumento posso usare? Impossibile cercare perché non so quale parola chiave utilizzare. grazie – naz

-1

in XML modificare il testo ha la proprietà: android: capitalizzare = ""

+1

Ma saranno le piccole capitali come vuole OP? Non sono sicuro che lo –

+0

provi prima questo in xml. – deepak825

+0

@ deepak825 qualsiasi cosa tu fornisca qui come risposta dovrebbe essere aggiunta nei commenti. –

5

Ci scusiamo per il trascinamento di una domanda molto vecchio .

Mi è piaciuto l'approccio di @kcoppock a questo, ma sfortunatamente il carattere che sto usando manca dei caratteri a caratteri piccoli. Sospetto che molti altri si troveranno in questa situazione.

Questo mi ha spinto a scrivere un piccolo metodo util che prenderà una stringa mista (ad es.Small Caps) e creare una stringa formattabile che può contenere comeSᴍᴀʟʟ Cᴀᴘs ma utilizza solo i caratteri A-Z standard.

  • Funziona con qualsiasi tipo di carattere che ha i caratteri A-Z - niente di speciale richiesto
  • È facilmente utilizzabile in un TextView (o qualsiasi altra vista basato su testo, se è per questo)
  • Non fa richiede alcun HTML
  • non richiede alcuna modifica delle corde originali

ho posato il codice qui: https://gist.github.com/markormesher/3e912622d339af01d24e

0

Basta chiamare questa funzione getSmallCaps (testo):

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

Com'è questa piccola capsula? –

0

Questo non è il mio codice, ma le sue opere perfettamente.

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

Esempio:

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