Potential Reach
• Arabic: 295 million native speakers
• Urdu: 66 million native speakers
• Persian: 45 million native speakers
Nationalencyklopedin, 2010
Slide 4
Slide 4 text
Statistics - Q1 2015
• 95% of phones shipped in MEA are iOS / Android
• shipments of iOS/Android phones “increased by a
combined 67% year on year”
IDC Press Release, July 12th, 2015
Slide 5
Slide 5 text
–IDC Press Release, July 12th, 2015
“In the Middle East, Android currently
represents 80% of market's volume, while iOS
accounts for 17%; in Africa, these figures
stand at 89% and 7%, respectively.”
Resolving Layout Direction
• android:supportsRTL - if not, return LTR
• based on android:layoutDirection
• LAYOUT_DIRECTION_RTL or
LAYOUT_DIRECTION_LTR
• LAYOUT_DIRECTION_LOCALE
• LAYOUT_DIRECTION_INHERIT
Slide 24
Slide 24 text
Resolving Layout Direction
• for the inherit case, ViewRootImpl sets top level
direction to use Locale.
• resolving Locale happens in TextUtils (17+)
• TextUtils gets information from ICU
Mirroring Layouts
• ldrtl / ldltr resource qualifiers
• lower priority than -lang
• useful for mirroring drawables
Slide 32
Slide 32 text
Building Android
Components
Slide 33
Slide 33 text
Supporting Gravity in
ViewGroups
Slide 34
Slide 34 text
if ((gravity & RELATIVE_LAYOUT_DIRECTION) > 0) {
if ((gravity & Gravity.START) == Gravity.START) {
if (layoutDirection == View.LAYOUT_DIRECTION_RTL) {
// start resolving to right
} else {
// start resolving to left
}
} else if ((gravity & Gravity.END) == Gravity.END) {
if (layoutDirection == View.LAYOUT_DIRECTION_RTL) {
// end resolving to left
} else {
// end resolving to right
}
}
} else if ((gravity & Gravity.LEFT) == Gravity.LEFT) {
// left
} else if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) {
// right
}
Gravity.apply(
gravity, w, h, container, outRect,
layoutDirection);
gravity of whatever we want to position, ex
Gravity.START | Gravity.TOP
Slide 45
Slide 45 text
Gravity.apply(
gravity, w, h, container, outRect,
layoutDirection);
width and height of whatever we’re trying to position
Slide 46
Slide 46 text
Gravity.apply(
gravity, w, h, container, outRect,
layoutDirection);
a Rect in which the item will be positioned.
should be at least as large as the item.
Slide 47
Slide 47 text
Gravity.apply(
gravity, w, h, container, outRect,
layoutDirection);
the frame of the item we’re trying to place
Slide 48
Slide 48 text
Gravity.apply(
gravity, w, h, container, outRect,
layoutDirection);
the layout direction, for translating start and end
LinearLayout
int start = 0;
int dir = 1;
// In case of RTL, start drawing from the last child.
if (isLayoutRtl) {
start = count - 1;
dir = -1;
}
for (int i = 0; i < count; i++) {
int childIndex = start + dir * i;
final View child = getVirtualChildAt(childIndex);
// ...
}
Text Direction
• default is TEXT_DIRECTION_INHERIT
• ViewRootImpl sets this to
TEXT_DIRECTION_FIRST_STRONG
Slide 84
Slide 84 text
No content
Slide 85
Slide 85 text
Slide 86
Slide 86 text
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rtl_text);
// Ahmed in English, ﺪﻤﺣأ in Arabic
String name = getString(R.string.name);
String s = getString(R.string.name_format);
TextView tv = (TextView) findViewById(R.id.first);
tv.setText(String.format(s, name, 3));
}
Slide 87
Slide 87 text
No content
Slide 88
Slide 88 text
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rtl_text);
// Ahmed in Arabic, ﺪﻤﺣأ in English
String name = getString(R.string.name_opposite);
String s = getString(R.string.name_format);
TextView tv = (TextView) findViewById(R.id.first);
tv.setText(String.format(s, name, 3));
}
Slide 89
Slide 89 text
No content
Slide 90
Slide 90 text
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rtl_text);
// Ahmed in Arabic, ﺪﻤﺣأ in English
String name = getString(R.string.name_opposite);
String s = getString(R.string.name_format);
BidiFormatter formatter = BidiFormatter.getInstance();
name = formatter.unicodeWrap(name);
TextView tv = (TextView) findViewById(R.id.first);
tv.setText(String.format(s, name, 3));
}
Slide 91
Slide 91 text
No content
Slide 92
Slide 92 text
Tips
Slide 93
Slide 93 text
Tips
• android:supportsRTL=“true”
• for layout parameters, add START and END in
addition to RIGHT and LEFT
• be careful when mixing RTL and LTR text
Slide 94
Slide 94 text
Tips
• Be wary when using the default locale
• ship RTL to 17+ to save a lot of work
• test layouts and views in RTL and LTR on various
api versions