Android RTL 语言适配

RTL 语言,即 right to left language,也就是右对齐的语言,与一般语言按照左对齐的方式不同,需要进行特别适配。

  1. AndroidManifest.xml 文件中,增加 android:supportsRtl 属性值为 true

     <application
         ...
         android:supportsRtl="true">
    
     </application>
    
  2. 使用 start/end 代替 left/right 属性值。

    官方给出的需要替换的属性值列表如下:
    官方列出的属性值

    Android 对 RTL 的支持,是从 Android 4.2 版本开始的。如果项目支持的最低版本大于 4.2,可以全部替换;如果项目需要支持 4.2 以下的版本,也就是项目的 minSdkVersion 小于 17 的话,两类属性值还是要同时使用。由于低于 4.2 的版本中不识别 android:supportsRtlstart/end 类属性,因此不受影响。

    除手动替换外,使用 Studio 开发,软件提供了自动化操作的支持,可以在 RefactorAdd RTL Support Where Possible 来开启 RTL 的自动调整:

    自动调整

    在布局选项中勾选第一项,就能将布局文件中仍然存在的 left/right 属性 自动修改为 start/end;如果项目支持的最低版本小于 4.2 ,还需要勾选第二项。

    不过当自动替换完成以后,还是要进行手动测试,以确保完全修改。可以进行全局搜索,看看是否还存在仅支持 LTR(left to right) 的属性。

  3. 其他细节调整

    • EditViewTextView 等文本控件,还需在布局文件中添加以下属性:

      android:textAlignment="viewStart"
      android:gravity="start"
      android:textDirection="locale"
      

      其中,

      • android:textAlignment 是专门用来指定文本的对齐位置的,可选值有"inherit"、"gravity"、"textStart"、"textEnd"、"center"、"viewStart"、"viewEnd" 等。对于文本控件来说,其优先级高于 gravity ,而 textAlignment 为空或为 "gravity" 时,文本的对齐方式就由 gravity 属性确定。
      • gravitylayout_gravity 属性的区别在于,gravity 指定的是控件内部的子控件或文本的停靠位置,layout_gravity 指定的是控件在其外部容器(父布局)中的停靠位置。
    • 资源适配:对 Drawable 文件(mipmap 文件同此)来说,有些场景下需要适配 RTL,比如返回「←」的图标也需要替换成「→」。修改方式是创建 drawable-ldrtl 目录,将翻转后的图标,放在这个目录下。如果需要限定 dpi,可以在目录名后面追加:

    res/
        drawable/
            a.png  
        drawable-ldrtl/
            a.png  // 对标 drawable/a.png 的 RTL 图标
        drawable-xhdpi/
            b.png  
        drawable-ldrtl-xhdpi/
            b.png  // 对标 drawable-xhdpi/b.png 的 RTL 图标
    
    • 布局适配:对 layout 文件来说,可以在原有 layout 文件夹后增加限定符,生成新文件夹 layout-ldrtl, 用来放置镜像语言专用的布局;也可以针对语言进行单独定制,比如阿拉伯语可以用 layout-ar/
    res/
        layout/
            main.xml  // 默认布局
        layout-ar/
            main.xml  // 阿拉伯语布局
        layout-ldrtl/
            main.xml  // RTL 布局
    
    • 使用代码判断是否是镜像语言:使用 TextUtils 工具类中的方法:
    private static boolean isRTL() {
        int locale = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault());
        return locale == View.LAYOUT_DIRECTION_RTL;
    }
    
    • 布局方向的改变可能会影响原有的 setX()setY() 方法带来的效果,需要手动排查。
    • 在右到左布局下,其坐标布局方式不变,getLeft()getRight()等方法返回值不变。变的是布局约束,view的绘制受rightstart)约束。
    • 在代码中修改 view 的位置,可以采用 ViewGroup.MarginLayoutParams 来设置margin,或者采用 layout 的方式。
posted @ 2022-08-31 15:47  wx2020  阅读(1120)  评论(0编辑  收藏  举报