安卓如何确定设备是否采用从右到左的语言/布局?

43

有没有办法确定设备是否使用从右到左的语言(例如阿拉伯语)而不是从左到右的语言(英语)?

需要与旧 API 级别兼容(最低支持到 10)

解决方案

我最终采用了被接受答案中的 XML 方法。在稍后的开发过程中,我还添加了此处指定的代码,以处理无法访问 getResources() 的情况。

在 Android 中识别 RTL 语言

更多信息

此问题仍然受到很多关注;我想指出的另一件事是:当我最初提出这个问题时,我认为部分原因是为了帮助解决在 RTL vs LTR 中显示不同指向箭头的问题 - 另一种实现方法是将可绘制资源放置在 standardldrtl 目录中 - 这意味着无需代码即可确定要显示哪一个!

9个回答

69

您可以创建一个名为values-ldrtl的文件夹,并在其中创建一个名为isrighttoleft.xml的XML文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="is_right_to_left">true</bool>
</resources>

在您的values文件夹中,使用相同的文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="is_right_to_left">false</bool>
</resources>

最后的代码如下:

boolean isRightToLeft = getResources().getBoolean(R.bool.is_right_to_left);

只有在特定设置(例如语言)为从右到左阅读的语言的设备上,才会使用values-ldrtl。


1
在那些 XML 文件的第一行末尾加上一个 "?>" 可以保证语法正确。 - Danuofr
谢谢。刚刚添加了它们... ;) - ezcoding
我在我的字符串资源文件中添加了这行代码。不需要为此创建特殊的文件。 - Atara
唯一有效的答案 - ucMedia
这会在旧的安卓设备上崩溃。 - EmmanuelMess
显示剩余4条评论

44

我认为这是更好的方式:

val isLeftToRight = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_LTR

文档:

https://developer.android.com/reference/android/support/v4/text/TextUtilsCompat.html#getLayoutDirectionFromLocale(java.util.Locale)

或者,如果您的 minAPI 版本为 17 或更高,则可以直接使用此方法:

val isLeftToRight=TextUtils.getLayoutDirectionFromLocale(Locale.getDefault())==View.LAYOUT_DIRECTION_LTR

Docs:

https://developer.android.com/reference/android/text/TextUtils.html#getLayoutDirectionFromLocale(java.util.Locale)


2
我刚在设备语言设置为阿拉伯语的 Android 10 上进行了测试,而我的应用程序没有翻译成阿拉伯语。Locale.getDefault() 返回 en_USLTR 布局方向。也许这个方法获取的是 应用程序 的语言环境布局方向,而不是设备的? - Sam
@Sam 在这种情况下是正确的。如果应用程序是英文的,您希望将其视为LTR,而不考虑设备的语言。 - Miloš Černilovský
@Sam Locale.getDefault() 应该返回当前操作系统的语言环境。也许您没有正确设置它,或者您没有使用更新后的 Locale.getDefault() 函数再次调用该函数。代码使用其所拥有的内容运行。如果它说是英语,则为LTR。 - android developer

28

你不需要视图来获取它。在这里查看我的答案:https://dev59.com/fF8d5IYBdhLWcg3wsT0b#47119946 - android developer

10

检测应用程序布局方向的 Kotlin 代码:

 val config = resources.configuration
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        if (config.layoutDirection == View.LAYOUT_DIRECTION_LTR) {
           // showAlertMsg("LTR")
        } else {
           // showAlertMsg( "RTL")
        }
    }
    else {
        //TODO("VERSION.SDK_INT < JELLY_BEAN_MR1")
           }

10
如果你正在使用 Core KTX,你可以使用以下内容:
if (Locale.getDefault().layoutDirection == LayoutDirection.RTL)

1
如果API 19可以的话 - ror

5
如果这个网站仍然有相当数量的流量,人们应该考虑使用Configuration.getLayoutDirection(),适用于API 17+。它将返回LayoutDirection.LTR或LayoutDirection.RTL。我想ViewCompat.getLayoutDirection(android.view.View)将返回实际用于布局特定视图的方向。如果您正在做一些奇怪的事情,比如尝试确定哪个人应该在聊天屏幕的哪一侧(像我一样),这可能会有用。

有一种方法可以让它在所有API版本上运行,而不需要视图,请参见此处:https://dev59.com/fF8d5IYBdhLWcg3wsT0b#47119946 - android developer
我认为使用ViewCompat.getLayoutDirection(android.view.View)是很好的选择,因为在某些视图中硬编码方向以避免在RTL语言中旋转或反之亦然是很常见的。 - David
海报问道:“有没有一种方法可以确定设备是否使用从右到左的语言”。我的答案是,Configuration 中确实有一种方法可以做到这一点。而那些在 View 和 ViewCompat 中被建议的方法,只检查特定的 View,而不是整个设备。 - androidguy

2
那很简单,只需使用:isRtll()
override fun isRtl(): Boolean {
    return super.isRtl()
}

玩得开心!


1
如果你的Build.VERSION.SDK_INT大于JELLY_BEAN (16),你可以使用这个:
val locale = Locale.getDefault() 
val isLtr = TextUtils.getLayoutDirectionFromLocale(locale) == ViewCompat.LAYOUT_DIRECTION_LTR

0

我需要一个 Bidi 的实例,对吧?不管怎样,我找到了一个看起来能够工作的解决方案。谢谢你! - joshkendrick
是的,您必须实例化一个。 - HappyCactus
1
请发布您找到的解决方案,以供将来参考。谢谢。 - HappyCactus
你不需要创建任何新实例。你可以使用这个链接代替:https://dev59.com/fF8d5IYBdhLWcg3wsT0b#47119946 - android developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接