Android RTL布局(阿语等反转UI)适配处理
介绍
我们语言的阅读习惯为从左向右,即LTR(Left-To-Right),而RTL(Right-To-Left)正好相反,阅读习惯为从右向左,常见语言有阿拉伯语,希伯来语等。
如果APP有面向国际化和海外市场的需求,则需要针对RTL布局进行适配调优。
配置
APP支持RTL布局,需要在AndroidManifest.xml
的<application>
中,添加android:supportsRtl=true
,在targetSdk>=17时激活,设为false或小于17则关闭
布局配置
调整 layout布局属性,使用 start/end
,无特殊情况则避免使用 left/right
资源文件配置
图片资源创建
drawable-ldrtl
或mipmap-ldrtl
目录,将翻转的图片资源放在目录下,可以限定dpi,例如drawable-ldrtl-xhdpi
。布局文件创建layout-idrtl目录,可以增加语言限定,例如阿拉伯语layout-ar/。
其他资源文件同理,添加
ldrtl
或ar
RTL语言进行适配,建议使用前者。
细节技巧
RTL判断
部分自定义控件不支持start/end
属性,则需要判断是否为RTL布局:
1 | public static boolean isRtl() { |
判断字符串是否为RTL字符串(通过首字符判断)
1 | public static boolean isRtlStr(String text) { |
开发踩坑
ViewPager 不支持 RTL ,需要使用 ViewPager2 或 RTLViewPager (GitHub) ,优先前者,后者建议用作老项目兼容。
优先使用Google官方的拓展库,例如Flow布局可以用RecyclerView的拓展
FlexboxLayoutManager
,会自动处理列表倒序显示。字符串数字会转为阿拉伯符号数字,涉及到金额时间,使用
String.format()
设为Locale.ENGLISH
转换为普通数字。部分自定义控件不支持
start/end
属性,只能使用left/right
,例如Reat(),需要手动判断isRTL()进行适配处理。使用 TextView,尤其是列表中,width尽量避免使用
match_parent
,android:layout_weight="1"
或固定宽度
,否则在RTL布局下,阿语会在右侧显示,中文等语言在左侧显示,造成显示异常;
可以在TextView外部包裹LinearLayout等父布局,父布局设为match_pareht,在RTL布局可以正常显示;
或推荐使用 ConstraintLayout(约束布局),设置好view的start和end参数后,搭配app:layout_constrainedWidth="true"
在不挤压其他View的情况下换行或显示省略号,类似maxWidth但自适应最大宽度;
如果父布局为固定宽度
或match_parent
,则需要添加app:layout_constraintHorizontal_bias="0"
和app:layout_constraintHorizontal_chainStyle="packed"
,防止内容不足时显示异常。TextView会默认选择第一个字符设置语言。
Drawable的autoMirrored属性,设置为true,可以让drawable在RTL布局下反转,在Java代码中也可设置。
1
2
3
4<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:autoMirrored="true">
...
</layer-list>ImageView可以设置
scaleX(-1)
对图像进行反转处理。如果布局不需要反转,可以设置
android:layoutDirection = "ltr"
。不建议使用
+
号拼接字符串,也不要使用 TextView 在布局拼接,用"ID %s"
,"ID %d"
,":ID ${user.uid}"
等方法输入,有必要可在string.xml中专门配置字符串。
总结
很多适配细节都是开发中的良好习惯,在开发时注意到可以省去很多麻烦。