Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TextViews and Localization

TextViews and Localization

9904145db476b6658d75fff27b1929ed?s=128

Elliott Chenger

August 27, 2015
Tweet

Transcript

  1. TextViews & Localization Elliott Chenger @echenger

  2. Overview •Android Text Rendering •Typography and Android •Internationalization and Localization

    •Localize All the Androids
  3. Android Text Rendering Let me explain you

  4. Android Text Rendering Let me explain you Slightly Abridged

  5. Widget Text Graphics Three major packages that help render text

  6. TextView Layout Text Paint Other Classes in android.text Widget Text

    Graphics
  7. TextView Layout Text Paint Other Classes in android.text Widget Text

    Graphics
  8. Layout TextView Text Paint Other Classes in android.text Widget Text

    Graphics
  9. Canvas Layout TextView Text Paint Other Classes in android.text Widget

    Text Graphics
  10. Typography & Android

  11. Imaginary line which a line of text rests upon Baseline

    getBaseline(); getLineBounds(0, null); getLineBounds(1, null);
  12. Imaginary line which a line of text rests upon Baseline

    getBaseline(); getLineBounds(0, null); getLineBounds(
  13. Baseline getBaseline(); getLineBounds(0, null); public final int getLineBaseline(int line) {


    // getLineTop(line+1) == getLineTop(line)
 return getLineTop(line+1) - getLineDescent(line);
 }
  14. Imaginary line which a line of text rests upon Baseline

    getBaseline(); getLineBounds(0, null); getLineBounds(
  15. Imaginary line which a line of text rests upon Baseline

    getBaseline() getLineBounds( getLineBounds(1, null);
  16. Imaginary line running along the top of non-ascending, lowercase letters

    Meanline
  17. Imaginary line running along the top of non-ascending, lowercase letters

    Meanline No Known Android API
  18. The invisible line marking the farthest distance between the baseline

    and the top of the glyph. Ascent Line textView.getPaint().ascent()
  19. textView.getPaint().ascent() /**
 * Return the distance above (negative) the baseline

    (ascent) based on the
 * current typeface and text size.
 *
 * @return the distance above (negative) the baseline (ascent) based on the
 * current typeface and text size.
 */ Ascent Line
  20. textView.getPaint() .getFontMetrics().top The invisible line marking the farthest distance between

    the baseline and the top of the glyph. Ascent Line
  21. /**
 * The maximum distance above the baseline for the

    tallest glyph in
 * the font at a given text size.
 */ textView.getPaint().getFontMetrics().top Ascent Line
  22. The invisible line marking the lowest point of the descenders

    within a font. Descender Line textView.getPaint().descent()
  23. textView .getPaint() .getFontMetrics().bottom The invisible line marking the lowest point

    of the descenders within a font. Descender Line
  24. The spacing between the baselines of each line of text

    Leading textView .setLineSpacing(add,mult); “Multiple people defending fragment API and behavior pretty hard around the internet lately. Enjoy your straw houses, little pigs.” “Multiple people defending fragment API and behavior pretty hard around the internet lately. Enjoy your straw houses, little pigs.”
  25. The spacing between the baselines of each line of text

    Leading textView .setLineSpacing(add,mult); Add: pixels added to each line height “Multiple people defending fragment API and behavior pretty hard around the internet lately. Enjoy your straw houses, little pigs.” “Multiple people defending fragment API and behavior pretty hard around the internet lately. Enjoy your straw houses, little pigs.”
  26. The spacing between the baselines of each line of text

    Leading textView .setLineSpacing(add,mult); Add: pixels added to each line height Mult: float to multiply each line height by. Initially 1.0 “Multiple people defending fragment API and behavior pretty hard around the internet lately. Enjoy your straw houses, little pigs.” “Multiple people defending fragment API and behavior pretty hard around the internet lately. Enjoy your straw houses, little pigs.”
  27. Internationalization & Localization

  28. Internationalization Design a product from the ground up to be

    easily localizable
  29. Localization The act of making a product meet language and

    cultural requirements for a locale*.
  30. Locale A set of parameters that define a users language

    and country
  31. Locale in Android Locale.class getDefault() Returns the users preferred locale

    getDisplayLanguage() Get language name for default Locale getDisplayCountry() Get country name for default Locale
  32. Locale in Android res/values/strings.xml Resource Qualifiers res/values-fr/strings.xml res/values-ja/strings.xml res/values-en-rGB/strings.xml

  33. Locale in Android res/values/strings.xml Resource Qualifiers res/values-fr/strings.xml res/values-ja/strings.xml res/values-en-rGB/strings.xml Language

    Qualifier
  34. Locale in Android res/values/strings.xml Resource Qualifiers res/values-fr/strings.xml res/values-ja/strings.xml res/values-en-rGB/strings.xml Country

    Qualifier Language Qualifier
  35. Localize all the Androids

  36. 1.Identify target languages and locales 2.Design for localization 3.Manage Strings

    for localization 4.Translate UI Strings and other resources 5.Test your localized app 6.Prepare for localized app 7.Support international users after launch Google Localization Checklist
  37. 1.Identify target languages and locales 2.Design for localization (and develop

    your layouts
 using proper localization standards) 3.Manage Strings for localization 4.Translate UI Strings and other resources 5.Test your localized app 6.Prepare for localized app 7.Support international users after launch Google Localization Checklist
  38. Google Localization Checklist 1.Identify target languages and locales 2.Design for

    localization (and develop your layouts
 using proper localization standards) 3.Manage Strings for localization 4.Translate UI Strings and other resources 5.Test your localized app 6.Prepare for localized app 7.Support international users after launch
  39. Elliott’s Development Localization Checklist

  40. 1.Support RTL Elliott’s Development Localization Checklist

  41. Support RTL LTR RTL

  42. <application
 android:allowBackup="true"
 android:icon="@mipmap/ic_launcher"
 android:label="@string/app_name"
 android:supportsRtl="true"
 android:theme="@style/AppTheme" > Support RTL

  43. <application
 android:allowBackup="true"
 android:icon="@mipmap/ic_launcher"
 android:label="@string/app_name"
 android:supportsRtl="true"
 android:theme="@style/AppTheme" > Support RTL

  44. <com.omitneedlesscode.droidconnyc.DebugTextView
 android:text="@string/test_string"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/example_text_view"
 android:layout_marginStart="20dp"
 android:layout_marginEnd="20dp"
 android:textSize="18sp"/> Support RTL

  45. Support RTL <com.omitneedlesscode.droidconnyc.DebugTextView
 android:text="@string/test_string"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/example_text_view"
 android:layout_marginStart="20dp"
 android:layout_marginEnd="20dp"
 android:textSize="18sp"/>

    API 17+
  46. Support RTL LTR RTL Margin Start Margin Start

  47. Support RTL LTR RTL Margin End

  48. 1.Support RTL 2.Make font file a localized String Elliott’s Development

    Localization Checklist
  49. <resources>
 <declare-styleable name="DebugTextView">
 <attr name="font" format="string"/>
 </declare-styleable>
 </resources> res/values/attr.xml Fonts

  50. <string name=“noto_font"> fonts/NotoSans-Regular.ttf </string> res/values/strings.xml (for each locale) Fonts

  51. private void loadCustomFont(Context context, AttributeSet attrs) {
 TypedArray typedArray =


    context.obtainStyledAttributes(attrs, R.styleable.DebugTextView);
 String fontLocation = typedArray.getString(R.styleable.DebugTextView_font);
 Typeface customTypeFace = Typeface.createFromAsset(getContext().getAssets(), fontLocation);
 super.setTypeface(customTypeFace);
 } CustomTextView.java Cache in memory Fonts
  52. Fonts public DebugTextView(Context context, AttributeSet attrs) {
 super(context, attrs);
 loadCustomFont(context,attrs);


    } CustomTextView.java Do for all constructors
  53. 1.Support RTL 2.Make font file a localized String 3.Mind font

    padding Elliott’s Development Localization Checklist
  54. <com.omitneedlesscode.droidconnyc.DebugTextView
 android:text="@string/test_string"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/example_text_view"
 style="@style/localized_text_view"
 android:includeFontPadding="false"
 android:textSize="28sp"/> Don’t set

    include font padding to false Font Padding
  55. <com.omitneedlesscode.droidconnyc.DebugTextView
 android:text="@string/test_string"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/example_text_view"
 style="@style/localized_text_view"
 android:includeFontPadding="false"
 android:textSize="28sp"/> Don’t set

    include font padding to false Font Padding
  56. <com.omitneedlesscode.droidconnyc.DebugTextView
 android:text="@string/test_string"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/example_text_view"
 style="@style/localized_text_view"
 android:includeFontPadding="false"
 android:textSize="28sp"/> Don’t set

    include font padding to false Font Padding
  57. Font Padding

  58. Font Padding

  59. 1.Support RTL 2.Make font file a localized String 3.Mind font

    padding 4.One layout to rule them all Elliott’s Development Localization Checklist
  60. “In cases where your UI can't accommodate text in one

    of your target languages, you can create an alternative layout for that language only.” Google Localization Checklist https://developer.android.com/distribute/tools/localization-checklist.html One Layout
  61. “In cases where your UI can't accommodate text in one

    of your target languages, you can create an alternative layout for that language only.” “While the flexibility of alternative layouts exists it can also make your apps harder to maintain over time. In general, using a single, more flexible layout is preferred.” Google Localization Checklist https://developer.android.com/distribute/tools/localization-checklist.html One Layout
  62. “In cases where your UI can't accommodate text in one

    of your target languages, you can create an alternative layout for that language only.” “While the flexibility of alternative layouts exists it can also make your apps harder to maintain over time. In general, using a single, more flexible layout is preferred.” Google Localization Checklist https://developer.android.com/distribute/tools/localization-checklist.html One Layout
  63. <com.omitneedlesscode.droidconnyc.DebugTextView
 android:text="@string/test_string"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/example_text_view"
 android:layout_marginStart="20dp"
 android:layout_marginEnd="20dp"
 android:textSize="28sp"/> API 17+

    One Layout
  64. <Layout> <com.omitneedlesscode.droidconnyc.DebugTextView
 android:text="@string/test_string"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/example_text_view"
 android:layout_marginStart="20dp"
 android:layout_marginEnd="20dp"
 android:textSize=“28sp"/> </Layout>

    <Layout> <com.omitneedlesscode.droidconnyc.DebugTextView
 android:id="@+id/example_text_view"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginRight="20dp"
 android:layout_marginLeft="20dp"
 android:text="@string/test_string"
 android:textSize=“28sp"/> </Layout>
 API 17+ API <17 One Layout
  65. <Layout> <com.omitneedlesscode.droidconnyc.DebugTextView
 android:text="@string/test_string"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/example_text_view"
 android:layout_marginStart="20dp"
 android:layout_marginEnd="20dp"
 android:textSize=“28sp"/> </Layout>

    <Layout> <com.omitneedlesscode.droidconnyc.DebugTextView
 android:id="@+id/example_text_view"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginRight="20dp"
 android:layout_marginLeft="20dp"
 android:text="@string/test_string"
 android:textSize=“28sp"/> </Layout>
 API 17+ API <17 One Layout
  66. <style name="localized_text_view">
 <item name="android:layout_marginStart">20dp</ item>
 </style> <style name="localized_text_view">
 <item name="android:layout_marginRight">60dp</

    item>
 </style> 
 values-v17 values One Layout
  67. One Layout <com.omitneedlesscode.droidconnyc.DebugTextView
 android:text="@string/test_string"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/example_text_view"
 style="@style/localized_text_view"
 android:textSize="28sp"/>

  68. 1.Support RTL 2.Make font file a localized String 3.Mind font

    padding 4.One layout to rule them all 5.Be careful with Spans Elliott’s Development Localization Checklist
  69. Don’t Span Everything

  70. Don’t Span Everything

  71. Don’t Span Everything

  72. 1.Support RTL 2.Make font file a localized String 3.Mind font

    padding 4.One layout to rule them all 5.Be careful with Spans 6.Localize Line Heights Elliott’s Development Localization Checklist
  73. <com.omitneedlesscode.droidconnyc.DebugTextView
 android:text="@string/test_string"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/example_text_view"
 android:lineSpacingMultiplier="0.8"
 style="@style/localized_text_view"
 android:textSize="28sp"/> Line Height

    Add/Mult
  74. Line Height Add/Mult

  75. Line Height Add/Mult

  76. Line Height Add/Mult

  77. Line Height Add/Mult

  78. <com.omitneedlesscode.droidconnyc.DebugTextView
 android:text="@string/test_string"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/example_text_view"
 android:lineSpacingMultiplier="0.8"
 style="@style/localized_text_view"
 android:textSize="28sp"/> Line Height

    Add/Mult
  79. Line Height Add/Mult <com.omitneedlesscode.droidconnyc.DebugTextView
 android:text="@string/test_string"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/example_text_view"
 android:lineSpacingMultiplier="@integer/line_mult"
 style="@style/localized_text_view"


    android:textSize="28sp"/>
  80. Line Height Add/Mult <resources>
 <item name="line_mult" format="float" type="integer">0.8</item>
 </resources> <resources>


    <item name="line_mult" format="float" type=“integer">1.0</item>
 </resources> values/integers.xml values-th/integers.xml
  81. 1.Support RTL 2.Make font file a localized String 3.Mind font

    padding 4.One layout to rule them all 5.Be careful with Spans 6.Localize Line Heights 7.Pseudolocalizations Elliott’s Development Localization Checklist
  82. Pseudolocalization

  83. Pseudolocalization buildTypes {
 debug{
 pseudoLocalesEnabled true
 }
 release {
 minifyEnabled

    false
 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 }
 }
  84. Pseudolocalization buildTypes {
 debug{
 pseudoLocalesEnabled true
 }
 release {
 minifyEnabled

    false
 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 }
 }
  85. Pseudolocalization

  86. Pseudolocalization Configure Device for Locale: en_XA

  87. Pseudolocalization

  88. None
  89. Elliott Chenger @echenger omitneedlesscode.com Special Thanks to:
 @ericboam