识别Android中的RTL语言

cya*_*ide 54 android right-to-left

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

由于API 17+为RTL和LTR提供了多种资源,我认为应该有一种方法,至少从API 17开始.

Mor*_*ang 72

Configuration.getLayoutDirection()获取它:

Configuration config = getResources().getConfiguration();
if(config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
    //in Right To Left layout
}
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是"在API级别17中添加"因此它不适用于旧版本. (3认同)
  • 当您在开发人员选项中使用"强制RTL布局方向"时,此解决方案也可以使用! (3认同)
  • 这就是 API 级别低于 17 的方法:http://stackoverflow.com/a/28568974/170842。 (2认同)
  • 在奥利奥它不会自动改变布局方向(可能是一个错误)所以这在奥利奥不起作用. (2认同)

Tim*_*man 50

@ 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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这会导致`locale.getDisplayName().charAt(0)`的`StringIndexOutOfBoundsException`.这似乎是一个[已知问题](https://bugs.openjdk.java.net/browse/JDK-6992272?page=com.atlassian.streams.streams-jira-plugin:activity-stream-issue-tab使用Java 7我现在的解决方案就像`final String language = application.getResources().getConfiguration().locale.getLanguage(); ``返回Strings.equals(语言,"iw")|| Strings.equals(语言,"ar")|| Strings.equals(语言,"他");` (3认同)

Mic*_*ael 22

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

if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL) {
    // The view has RTL layout
} else {
    // The view has LTR layout
}
Run Code Online (Sandbox Code Playgroud)

  • @DastakWall 是的,但它总是会返回 LTR (2认同)

Ely*_*uda 14

您可以使用支持库中的TextUtilsCompat.

TextUtilsCompat.getLayoutDirectionFromLocale(locale)


小智 9

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

ViewUtils.isLayoutRtl(View view);
Run Code Online (Sandbox Code Playgroud)

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


Pas*_*cal 8

我收集了很多信息,最后制作了我自己的,希望完整的RTLUtils课程.

它允许知道给定的Locale或View是否为'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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Inz*_* IT 7

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

boolean isRightToLeft = TextUtilsCompat.getLayoutDirectionFromLocale(Locale
               .getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL;
Run Code Online (Sandbox Code Playgroud)

或者适用于API 17或更高版本

boolean isRightToLeft = TextUtils.getLayoutDirectionFromLocale(Locale
               .getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL;
Run Code Online (Sandbox Code Playgroud)


Ron*_*TLV 6

您可以使用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
}
Run Code Online (Sandbox Code Playgroud)