在Android中识别RTL语言

除了针对所有RTL语言testing语言代码之外,是否有方法可以识别RTL(从右到左)的语言?

由于API 17+允许为RTL和LTR提供多个资源,因此我认为应该有一个方法,至less从API 17开始。

从Configuration.getLayoutDirection()获取它:

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

@氰化物的答案有正确的方法,但一个关键的错误。

Character.getDirectionality返回双向(双向)字符types 。 从左到右的文本是可预测的typesL,从右到左的文本也是可预测的typesR.但是,阿拉伯文本返回另一个types,types为AL。

我添加了一个typesR和typesAL的检查,然后手动testing每个Android附带的RTL语言:希伯来语(以色列),阿拉伯语(埃及)和阿拉伯语(以色列)。

正如您所看到的,这留下了其他从右到左的语言,所以我担心Android会添加这些语言,可能会有类似的问题,而且可能不会马上注意到。

所以我手动testing每个RTL语言。

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

所以看起来这应该很好:

 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送我正确的方向!

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

 if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL) { // The view has RTL layout } else { // The view has LTR layout } 

有一个非常简单的方法来检查视图的布局方向,但是在API 17之前的设备上会回到LTR:

 ViewUtils.isLayoutRtl(View view); 

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

我收集了很多信息,最后做了我自己的,希望完成的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; } } 

请享用 :-)

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

TextUtilsCompat.getLayoutDirectionFromLocale(locale)

为了在LTR和RTL模式下更精确地控制应用程序UI,Android 4.2包含以下新API以帮助pipe理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

谢谢大家。

如果您查看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; } 

这将适用于所有SDKS:

 private boolean isRTL() { Locale defLocale = Locale.getDefault(); return Character.getDirectionality(defLocale.getDisplayName(defLocale).charAt(0)) == Character.DIRECTIONALITY_RIGHT_TO_LEFT; } 

在build立图书馆时,你也总是需要通过使用来检查应用程序是否支持RTL

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

当应用程序在RTL语言环境上运行时,但它没有在manifest android:supportsRtl="true"声明,那么它在LTR模式下运行。

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; } } 

只要使用这个代码:

  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的lavels。

由于英文设备支持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());