Android에서 RTL 언어 식별
모든 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는 양방향 (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;
}
나에게 올바른 방향을 보내 주신 @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 클래스를 만들었습니다.
주어진 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;
}
}
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
모두에게 감사합니다.
If you look at the code of LayoutUtil.getLayoutDirectionFromLocale()
(and, I assume Confuiguration.getLayoutDirection()
as well), it ends up with analysing the starting letter of locale display name, using Character.getDirectionality
.
Since Character.getDirectionality
was around from Android 1, the following code will be compatible with all Android releases (even those, not supporting RTL correctly :)):
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;
}
When building library you also always need to check if application is supporting RTL by using
(getApplicationInfo().flags &= ApplicationInfo.FLAG_SUPPORTS_RTL) != 0
When application is running on RTL locale, but it isn't declared in manifest android:supportsRtl="true"
then it is running in LTR mode.
This will work in all SDKS:
private boolean isRTL() {
Locale defLocale = Locale.getDefault();
return Character.getDirectionality(defLocale.getDisplayName(defLocale).charAt(0)) == Character.DIRECTIONALITY_RIGHT_TO_LEFT;
}
Just use this 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
}
This will work for all Android API lavels.
You can detect if a string is RTL/LTR with Bidi. Example:
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
}
Native RTL support in 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;
}
}
Because English language devices are supporting RTL, you can use this code in your MainActivity to change device language to english and you don't need to "supportRTL" code.
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());
ReferenceURL : https://stackoverflow.com/questions/18996183/identifying-rtl-language-in-android
'program story' 카테고리의 다른 글
AngularJS의 입력 필드에서 첫 번째 문자를 자동 대문자로 바꾸는 방법은 무엇입니까? (0) | 2021.01.09 |
---|---|
Rails before_validation 스트립 공백 모범 사례 (0) | 2021.01.09 |
java.lang.String.split ()이 선행 빈 문자열을 만드는 것을 방지하는 방법은 무엇입니까? (0) | 2021.01.08 |
update-alternatives --config java 명령을 사용하는 방법 (0) | 2021.01.08 |
VB.Net Lambda 식을 작성하는 방법 (0) | 2021.01.08 |