引
近期公司項目需要開拓阿拉伯市場,故需要在APP端兼容阿拉伯語。
阿拉伯語與其他多語言不同之處在于其布局是由右到左排布的,與我們常見的從左到右的布局不同。故需要修改部分代碼的寫法以兼容右到左布局。
開發(fā)問題及修改方法
| 模塊 | 注意功能點 | 解決方法 |
|---|---|---|
| 字符串文件String.xml | 翻譯校驗 | 注意占位符是否正常存在 |
| 貨幣符號 | 阿拉伯貨幣符號會使金額在前符號在后 | 通過代碼中貨幣切換方法轉變順序 |
| 貨幣金額 | 在部分語種下金額小數(shù)點會變成逗號 | 通過代碼中貨幣切換方法中調用DecimalFormatSymbols 指定LOCAL為US,保持小數(shù)點詳見注釋1 |
| 布局文件xml | paddingLeft/paddingRight | 增加paddingStart/paddingEnd |
| marginLeft/lmarginRight | 增加marginStar/lmarginEnd | |
| drawableLeft/drawableRight | 增加drawableStart/drawableEnd詳見注釋2 | |
| TextView,EditText中RTL布局下英語無法靠右顯示的問題 | 在Style文件中設置特定屬性統(tǒng)一修改詳見注釋3 | |
| FrameLayout中靠左子View未設置Start屬性時,無法兼容RTL布局 | 添加android:layout_gravity=start | |
| 圖標翻轉 | ImageView | 設置rotationY為180,可通過在不同布局的xml文件中聲明 |
| TextView中Drawable | 圖標素材翻轉 | |
| 代碼中動態(tài)設置間距 | setMargins | 根據(jù)Left,Right參數(shù)值在下方分別添加setMarginStart和setMarginEnd |
| setPadding | 替換為setPaddingRelative | |
| TextView設置Drawable | setCompoundDrawables | 替換為setCompoundDrawablesRelative |
| RecycleView分割線 | RTL布局中分割線不會相應替換 | 創(chuàng)建基類ItemDecoration,在getItemOffsets方法中根據(jù)作用布局決定是否進行l(wèi)eft right調換詳見注釋4 |
| 自定義View | 自定義圓角屬性未隨著RTL布局變換 | 獲取對應圓角屬性時,根據(jù)布局方向做相關值轉換 |
| 自定義動畫 | setTranslationX在RTL布局無法正常轉換 | RTL布局中設置的參數(shù)需取反,translationX -> -translationX |
| ViewPager | 官方不能兼容從右到左 | 1.引入第三方rtlViewPager 2.引入官方viewpager2 |
| 字符串拼接 | 阿拉伯語+英語位置錯誤 | 從左到右嵌入(U 202A) >從右到左嵌入(U 202B) >流行方向格式化(U 202C) |
注釋
1.在部分語種下金額小數(shù)點會變成逗號
//設置LOCAL為US,默認LOCAL為當前語言LOCAL
DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US);
//創(chuàng)建對應的格式化,取小數(shù)點后兩位
DecimalFormat format = new DecimalFormat("0.##", symbols);
//將金額轉換為String類型
format.format(d)
2.布局文件xml,Left變Start
XML文件的修改可通過Android Studio自帶的工具進行統(tǒng)一修改。
步驟為菜單欄Refactor->Add RTL Support Where Possible
3.TextView,EditText中阿拉伯語環(huán)境下英語無法靠右顯示的問題
<!-- 在BaseStyle中指定editTextStyle和android:textViewStyle -->
<style name="AppBaseTheme" parent="Theme.AppCompat.NoActionBar">
<item name="editTextStyle">@style/EditTextStyle.Alignment</item>
<item name="android:textViewStyle">@style/TextViewStyle.TextDirection</item>
</style>
<!--EditText Style-->
<style name="EditTextStyle.Alignment" parent="@android:style/Widget.EditText">
<item name="android:textAlignment">viewStart</item>
<item name="android:gravity">start</item>
<item name="android:textDirection">locale</item>
</style>
<!--TextView Style-->
<style name="TextViewStyle.TextDirection" parent="android:Widget.TextView">
<item name="android:textDirection">locale</item>
</style>
4.右到左布局中分割線不會相應替換
public abstract class BaseCustomRtlDecoration extends RecyclerView.ItemDecoration {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
getCustomItemOffsets(outRect, view, parent, state);
if (TextUtilsCompat.getLayoutDirectionFromLocale(
view.getContext().getResources().getConfiguration().locale) == ViewCompat.LAYOUT_DIRECTION_RTL){
//使用異或操作完成數(shù)據(jù)交換,以免創(chuàng)建額外變量。
outRect.right = outRect.left ^ outRect.right;
outRect.left = outRect.left ^ outRect.right;
outRect.right = outRect.left ^ outRect.right;
}
}
//所有子ItemDecoration實現(xiàn)此方法,用法與getItemOffsets一致
public void getCustomItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { }
}