介绍
系统会按照从右到左 (RTL) 的方向阅读阿拉伯语和希伯来语等语言。界面镜像 RTL 显示时,某些图标也应该被镜像。例如:ActionBar 中返回键向左,RTL 时应向右
默认情况下,在 Android 中,当布局方向是镜像时,不会镜像图标。您可以根据需要专门镜像相应的图标。
本文将分别介绍使用 Android View 和 Jetpack Compose 开发时怎样支持 RTL 图标,当布局方向为 RTL 时自动镜像图标。
1. Android View 支持 RTL 图标
使用 Android View (传统的视图/View)开发时有多种方式可以实现对 RTL 图标的支持。
1.1 Android 4.4 之前的版本
Android 4.4(API 级别:19)以前的 Android 版本中,如果您的应用包含应针对从右向左布局扭转其水平方向的图像,必须在 drawables-ldrtl
资源目录中添加镜像,这个目录中的资源将仅用于 RTL 语言。
1.2 通过 autoMirrored/setAutoMirrored()
Android 4.4(API 级别:19)或更高版本可以通过在 Drawable
资源上启用 [autoMirrored](https://developer.android.com/reference/android/R.attr?hl=zh-cn#autoMirrored)
属性,或通过 [setAutoMirrored()](https://developer.android.com/reference/android/graphics/drawable/Drawable?hl=zh-cn#setAutoMirrored(boolean))
方法,系统可以自动为您进行镜像。启用后,当布局方向为从右到左时,[Drawable](https://developer.android.com/reference/android/graphics/drawable/Drawable?hl=zh-cn)
将自动镜像。
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:autoMirrored="true"
android:height="24dp"
android:tint="#77A9F3"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>
1.3 通过 layout-ldrtl 目录
如果无法使用自动镜像或提供备用可绘制资源,ImageView
的 scaleX
属性还可用于镜像可绘制对象可以在 res/layout-ldrtl
目录中提供特定用于 RTL 的布局。
在布局文件中镜像 ImageView
:
<ImageView
android:id="@+id/my_icon"
android:layout_width="60dp"
android:layout_height="60dp"
android:scaleX="-1" />
1.4 通过编程方式实现镜像。
使用 getLayoutDirection
手动检查布局方向:
if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL) {
// TODO
}
以编程方式镜像 ImageView
的内容:
imageView.setScaleX(-1);
2. Jetpack Compose 支持 RTL 图标
当布局方向是镜像时,Jetpack Compose 也不会自动镜像图标,如果我们使用 Drawable 资源作为图标时,可以像上面提到的使用 autoMirrored
属性实现图标自动镜像。
但是如果我们使用 ImageVector
作为图标时,我们常用 material-icons
和 material-icons-extended
库定义的图标资源,这两个库中定义的 ImageVector
图标并没有设置 autoMirrored
属性,不能实现图标自动镜像,需要使用 Modifier.scale() 来镜像图标。
使用 Compose 的 icons 资源时,请注意:这里使用的
material-icons
和material-icons-extended
的版本是 **1.3.1
,**未来官方的库如果增加了镜像图标的默认实现,就不需要自己实现了。
- 使用
scale
镜像图标:
IconButton(onClick = { /*TODO*/ }) {
Icon(
modifier = Modifier.scale(scaleX = -1f, scaleY = 1f),
imageVector = Icons.Default.ArrowBack,
contentDescription = "content description - https://itmob.cn",
)
}
- 如果想更方便的实现 ImageVector 图标的镜像,可以创建一个 Modifier 的扩展函数来完成:
@Stable
fun Modifier.autoMirrored(): Modifier {
return if (Locale.getDefault().layoutDirection == LayoutDirection.RTL)
this.scale(scaleX = -1f, scaleY = 1f)
else
this
}
用法:
IconButton(onClick = { /*TODO*/ }) {
Icon(
modifier = Modifier.mirror(),
imageVector = Icons.Default.ArrowBack,
contentDescription = "content description - https://itmob.cn"
)
}