59

除了针对所有 RTL 语言测试语言代码之外,有没有办法识别 RTL(从右到左)语言?

由于 API 17+ 允许 RTL 和 LTR 使用多种资源,我认为应该有一种方法,至少从 API 17 开始。

4

16 回答 16

80

从Configuration.getLayoutDirection()获取它:

Configuration config = getResources().getConfiguration();
if(config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
    //in Right To Left layout
}
于 2013-09-25T04:37:46.413 回答
54

@cyanide 的答案有正确的方法,但有一个严重的错误。

Character.getDirectionality 返回双向 (bidi) 字符类型。从左到右的文本是可预测的 L 类型,从右到左也是可预测的 R 类型。但是,阿拉伯文本返回另一种类型,类型 AL。

我添加了对 R 型和 AL 型的检查,然后手动测试了 Android 附带的每种 RTL 语言:希伯来语(以色列)、阿拉伯语(埃及)和阿拉伯语(以色列)。

如您所见,这忽略了其他从右到左的语言,所以我担心随着 Android 添加这些语言,可能会出现类似的问题,并且可能不会立即注意到。

所以我手动测试了每种 RTL 语言。

  • 阿拉伯语 (العربية) = 类型 AL
  • 库尔德语 (کوردی) = AL 型
  • 波斯语 (فارسی) = AL 型
  • 乌尔都语 (اردو) = 类型 AL
  • 希伯来语 (עברית) = R 型
  • 意第绪语 (ייִדיש) = R 型

所以看起来这应该很好用:

public static boolean isRTL() {
    return isRTL(Locale.getDefault());
}

public static boolean isRTL(Locale locale) {
    final int directionality = Character.getDirectionality(locale.getDisplayName().charAt(0));
    return directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
           directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
}

感谢@cyanide 向我发送了正确的方向!

于 2014-04-21T18:44:37.363 回答
24

如果您使用的是支持库,则可以执行以下操作:

if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL) {
    // The view has RTL layout
} else {
    // The view has LTR layout
}
于 2015-02-17T18:54:33.240 回答
16

您可以使用支持库中的TextUtilsCompat

TextUtilsCompat.getLayoutDirectionFromLocale(locale)

于 2016-05-19T08:56:52.867 回答
9

有一种非常简单的方法可以检查视图的布局方向,但它在 API 17 之前的设备上回退到 LTR:

ViewUtils.isLayoutRtl(View view);

ViewUtils 类与 support v7 库捆绑在一起,因此如果您使用的是 appcompat 库,它应该已经可用。

于 2015-08-06T10:17:16.850 回答
9

如果要检查低于 17 的 API,可以像这样检查

boolean isRightToLeft = TextUtilsCompat.getLayoutDirectionFromLocale(Locale
               .getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL;

或 API 17 或更高版本

boolean isRightToLeft = TextUtils.getLayoutDirectionFromLocale(Locale
               .getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL;
于 2017-11-23T10:39:13.527 回答
8

我收集了很多信息,最后制作了自己的 RTLUtils 类,希望是完整的。

它允许知道给定的区域设置或视图是否为“RTL”:-)

package com.elementique.shared.lang;

import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;

import android.support.v4.view.ViewCompat;
import android.view.View;

public class RTLUtils
{

    private static final Set<String> RTL;

    static
    {
        Set<String> lang = new HashSet<String>();
        lang.add("ar"); // Arabic
        lang.add("dv"); // Divehi
        lang.add("fa"); // Persian (Farsi)
        lang.add("ha"); // Hausa
        lang.add("he"); // Hebrew
        lang.add("iw"); // Hebrew (old code)
        lang.add("ji"); // Yiddish (old code)
        lang.add("ps"); // Pashto, Pushto
        lang.add("ur"); // Urdu
        lang.add("yi"); // Yiddish
        RTL = Collections.unmodifiableSet(lang);
    }

    public static boolean isRTL(Locale locale)
    {
        if(locale == null)
            return false;

        // Character.getDirectionality(locale.getDisplayName().charAt(0))
        // can lead to NPE (Java 7 bug)
        // https://bugs.openjdk.java.net/browse/JDK-6992272?page=com.atlassian.streams.streams-jira-plugin:activity-stream-issue-tab
        // using hard coded list of locale instead
        return RTL.contains(locale.getLanguage());
    }

    public static boolean isRTL(View view)
    {
        if(view == null)
            return false;

        // config.getLayoutDirection() only available since 4.2
        // -> using ViewCompat instead (from Android support library)
        if (ViewCompat.getLayoutDirection(view) == View.LAYOUT_DIRECTION_RTL)
        {
            return true;
        }
        return false;
    }
}
于 2015-02-24T08:38:14.177 回答
4

您可以使用Bidi检测字符串是否为 RTL/LTR 。例子:

import java.text.Bidi;

Bidi bidi = new Bidi( title, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT );

if( bidi.isLeftToRight() ) {
   // it's LTR
} else {
   // it's RTL
}
于 2019-01-23T10:26:20.213 回答
3

为了在 LTR 和 RTL 模式下更精确地控制您的应用 UI,Android 4.2 包含以下新 API 来帮助管理 View 组件:

android:layoutDirection — attribute for setting the direction of a component's layout.
android:textDirection — attribute for setting the direction of a component's text.
android:textAlignment — attribute for setting the alignment of a component's text.
getLayoutDirectionFromLocale() — method for getting the Locale-specified direction

因此 getLayoutDirectionFromLocale() 应该可以帮助您。请参阅此处的示例代码:https ://android.googlesource.com/platform/frameworks/base.git/+/3fb824bae3322252a68c1cf8537280a5d2bd356d/core/tests/coretests/src/android/util/LocaleUtilTest.java

于 2013-09-25T05:18:36.283 回答
3

只需使用以下代码:

 public static boolean isRTL() {
   return isRTL(Locale.getDefault());
 }

 public static boolean isRTL(Locale locale) {
  final int directionality = Character.getDirectionality(locale.getDisplayName().charAt(0));
  return directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
       directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
 }

 if (isRTL()) {
   // The view has RTL layout
 }
 else {
   // The view has LTR layout
 }

这适用于所有 Android API lavel。

于 2016-05-08T16:14:38.810 回答
2

谢谢大家。

如果您查看LayoutUtil.getLayoutDirectionFromLocale()(并且,我也假设Confuiguration.getLayoutDirection())的代码,它最终会分析区域设置显示名称的起始字母,使用Character.getDirectionality.

由于Character.getDirectionality从 Android 1 开始,以下代码将与所有 Android 版本兼容(即使是那些,不正确支持 RTL :)):

public static boolean isRTL() {
    return isRTL(Locale.getDefault());
}

public static boolean isRTL(Locale locale) {
     return
        Character.getDirectionality(locale.getDisplayName().charAt(0)) ==
            Character.DIRECTIONALITY_RIGHT_TO_LEFT; 
}
于 2013-09-26T01:57:13.593 回答
2

在构建库时,您还需要始终检查应用程序是否支持 RTL,方法是使用

(getApplicationInfo().flags &= ApplicationInfo.FLAG_SUPPORTS_RTL) != 0

当应用程序在 RTL 语言环境中运行,但未在清单中声明时,android:supportsRtl="true"它会在 LTR 模式下运行。

于 2017-05-17T11:10:10.340 回答
1

这将适用于所有 SDK:

private boolean isRTL() {
    Locale defLocale = Locale.getDefault();
    return  Character.getDirectionality(defLocale.getDisplayName(defLocale).charAt(0)) == Character.DIRECTIONALITY_RIGHT_TO_LEFT;
}
于 2014-02-27T09:23:32.530 回答
0

Android 4.2 中的原生 RTL 支持

    public static ComponentOrientation getOrientation(Locale locale) 
    {
            // A more flexible implementation would consult a ResourceBundle
            // to find the appropriate orientation.  Until pluggable locales
            // are introduced however, the flexiblity isn't really needed.
            // So we choose efficiency instead.
            String lang = locale.getLanguage();
            if( "iw".equals(lang) || "ar".equals(lang)
                || "fa".equals(lang) || "ur".equals(lang) )
            {
                return RIGHT_TO_LEFT;
            } else {
                return LEFT_TO_RIGHT;
            }
    }
于 2013-09-25T04:55:05.457 回答
0

您可以轻松地使用它:

 if (getWindow().getDecorView().getLayoutDirection()== View.LAYOUT_DIRECTION_RTL) {
        // The view has RTL layout
    } else {
        // The view has LTR layout
    }
于 2020-08-16T17:34:08.163 回答
-1

因为英语设备支持 RTL,您可以在 MainActivity 中使用此代码将设备语言更改为英语,而无需“supportRTL”代码。

String languageToLoad  = "en"; // your language
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
于 2017-07-11T12:08:43.480 回答