すべてのRTL言語に対して言語コードをテストする以外に、RTL(右から左)言語を識別する方法はありますか?
API 17+ではRTLとLTRのいくつかのリソースが許可されているため、少なくともAPI 17からの方法があるはずです。
Configuration.getLayoutDirection() から取得します。
Configuration config = getResources().getConfiguration();
if(config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
//in Right To Left layout
}
@cyanideの答えには正しいアプローチがありますが、重大なバグがあります。
Character.getDirectionalityは、 双方向(双方向)文字タイプ を返します。左から右のテキストは予測可能なタイプLであり、右から左のテキストも予測可能なタイプRです。しかし、アラビア語のテキストは別のタイプ、タイプALを返します。
タイプRとタイプALの両方のチェックを追加し、すべてのRTL言語Androidに付属:ヘブライ語(イスラエル)、アラビア語(エジプト)、アラビア語(イスラエル))を手動でテストしました。
ご覧のとおり、これにより他の右から左の言語が除外されるため、Androidがこれらの言語を追加すると、同様の問題が発生する可能性があり、すぐに気付かない可能性があります。
そこで、各RTL言語を手動でテストしました。
したがって、これはうまくいくはずです:
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
}
サポートライブラリの TextUtilsCompat を使用できます。
TextUtilsCompat.getLayoutDirectionFromLocale(locale)
ビューのレイアウト方向を確認する非常に簡単な方法がありますが、API 17以前のデバイスではLTRにフォールバックします。
ViewUtils.isLayoutRtl(View view);
viewUtilsクラスはサポート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;
}
}
17未満のAPIを確認する場合は、このように確認できます
boolean isRightToLeft = TextUtilsCompat.getLayoutDirectionFromLocale(Locale
.getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL;
またはAPI 17以上の場合
boolean isRightToLeft = TextUtils.getLayoutDirectionFromLocale(Locale
.getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL;
LTRモードとRTLモードの両方でアプリUIをより正確に制御するために、Android 4.2にはViewコンポーネントの管理に役立つ次の新しいAPIが含まれています。
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;
}
ライブラリをビルドするときは、アプリケーションがRTLをサポートしているかどうかも常に確認する必要があります。
(getApplicationInfo().flags &= ApplicationInfo.FLAG_SUPPORTS_RTL) != 0
アプリケーションがRTLロケールで実行されているが、マニフェストで宣言されていない場合Android:supportsRtl="true"
その後、LTRモードで実行されます。
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
}
このコードを使用してください:
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レベルで機能します。
これはすべてのSDKSで機能します。
private boolean isRTL() {
Locale defLocale = Locale.getDefault();
return Character.getDirectionality(defLocale.getDisplayName(defLocale).charAt(0)) == Character.DIRECTIONALITY_RIGHT_TO_LEFT;
}
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;
}
}
英語のデバイスは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());