web-dev-qa-db-fra.com

Identifier la langue RTL dans Android

Existe-t-il un moyen d'identifier la langue RTL (de droite à gauche), à ​​part tester le code de langue par rapport à toutes les langues RTL?

Étant donné que l'API 17+ autorise plusieurs ressources pour RTL et LTR, je suppose qu'il devrait y avoir un moyen, au moins à partir de l'API 17.

53
cyanide

Obtenez-le de Configuration.getLayoutDirection () :

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

La réponse de @ cyanide a la bonne approche mais un bug critique.

Character.getDirectionality renvoie le type de caractère bidirectionnel (bidirectionnel) . Le texte de gauche à droite est un type prévisible L et de droite à gauche est également de type prévisible R. MAIS, le texte arabe renvoie un autre type, type AL.

J'ai ajouté une vérification pour le type R et le type AL, puis j'ai testé manuellement chaque langue RTL Android est livré avec: hébreu (Israël), arabe (Egypte) et arabe (Israël).

Comme vous pouvez le voir, cela laisse de côté d'autres langues de droite à gauche, donc je craignais que lorsque Android ajoute ces langues, il puisse y avoir un problème similaire et on ne le remarquerait pas tout de suite.

J'ai donc testé manuellement chaque langue RTL.

  • Arabe (العربية) = type AL
  • Kurde (کوردی) = type AL
  • Farsi (فارسی) = type AL
  • Ourdou (اردو) = type AL
  • Hébreu (עברית) = type R
  • Yiddish (ייִדיש) = type R

Il semble donc que cela devrait fonctionner à merveille:

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

Merci @cyanide de m'avoir envoyé la bonne direction!

50
Tim Trueman

Si vous utilisez la bibliothèque de support, vous pouvez effectuer les opérations suivantes:

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

Vous pouvez utiliser TextUtilsCompat à partir de la bibliothèque de support.

TextUtilsCompat.getLayoutDirectionFromLocale(locale)

13
Elyess Abouda

Il existe un moyen très simple de vérifier la direction de la mise en page d'une vue, mais cela revient au LTR sur les appareils pré API 17:

ViewUtils.isLayoutRtl(View view);

la classe ViewUtils est livrée avec la bibliothèque de support v7, elle devrait donc être déjà disponible si vous utilisez la bibliothèque appcompat.

9
Johannes

J'ai rassemblé de nombreuses informations et finalement créé ma propre classe, j'espère complète, RTLUtils.

Il permet de savoir si une locale ou une vue donnée est '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;
    }
}
8
Pascal

Vous pouvez vérifier comme ceci si vous voulez vérifier l'API inférieure à 17

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

OU pour API 17 ou supérieur

boolean isRightToLeft = TextUtils.getLayoutDirectionFromLocale(Locale
               .getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL;
7
Inzimam Tariq IT

Pour un contrôle plus précis de l'interface utilisateur de votre application en mode LTR et RTL, Android 4.2 inclut les nouvelles API suivantes pour vous aider à gérer les composants 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

Ainsi, getLayoutDirectionFromLocale () devrait vous aider. Reportez-vous à l'exemple de code ici: https://Android.googlesource.com/platform/frameworks/base.git/+/3fb824bae3322252a68c1cf8537280a5d2bd356d/core/tests/coretests/src/Android/util/LocaleUt .Java

3
SKN

Merci à tous.

Si vous regardez le code de LayoutUtil.getLayoutDirectionFromLocale() (et, je suppose que Confuiguration.getLayoutDirection() aussi), cela finit par analyser la lettre de départ du nom d'affichage des paramètres régionaux, en utilisant Character.getDirectionality.

Puisque Character.getDirectionality existait depuis Android 1, le code suivant sera compatible avec toutes les versions Android (même celles qui ne prennent pas RTL en charge correctement :))):

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

Lors de la création d'une bibliothèque, vous devez également toujours vérifier si l'application prend en charge RTL en utilisant

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

Lorsque l'application s'exécute sur les paramètres régionaux RTL, mais qu'elle n'est pas déclarée dans le manifeste Android:supportsRtl="true" puis il s'exécute en mode LTR.

2
Jedo

Vous pouvez détecter si une chaîne est RTL/LTR avec Bidi . Exemple:

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
}
1
RonTLV

Utilisez simplement ce code:

 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
 }

Cela fonctionnera pour tous les niveaux d'API Android Android.

1
Itiel Maimon

Cela fonctionnera dans tous les SDKS:

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

Prise en charge RTL native dans Android 4.2

    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;
            }
    }
0
Amit Prajapati

Étant donné que les appareils de langue anglaise prennent en charge RTL, vous pouvez utiliser ce code dans votre MainActivity pour changer la langue de l'appareil en anglais et vous n'avez pas besoin de "prendre en charge le code RTL".

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());
0
Taha khozooie