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.
Obtenez-le de Configuration.getLayoutDirection () :
Configuration config = getResources().getConfiguration();
if(config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
//in Right To Left layout
}
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.
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!
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
}
Vous pouvez utiliser TextUtilsCompat à partir de la bibliothèque de support.
TextUtilsCompat.getLayoutDirectionFromLocale(locale)
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.
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;
}
}
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;
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
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;
}
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.
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
}
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.
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;
}
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;
}
}
É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());