Форматирование форматирования RTL не работает для приложения
Я пытаюсь добавить поддержку языка RTL в моем приложении (особенно на арабском прямо сейчас). Я тоже буду поддерживать английский. Что я сделал:
- Установите minSdkVersion на 17
- Добавлен
android:supportsRtl="true"
для моего тега приложения в AndroidManifest.xml
- Поменял мои левые/правые атрибуты на начало/конец
Сначала я внес эти изменения вручную, затем я использовал пункт меню Android Studio "Refactor → Add RTL Support Where возможный...".
При предварительном просмотре файлов макета я вижу, что предварительный просмотр RTL правильно отражает пользовательский интерфейс; однако даже когда я использую "Force Layout Direction", мое приложение не отображает RTL-макет. Системный интерфейс перевернут, так что эта опция работает в целом.
Что еще нужно сделать, чтобы показать макет RTL? Я надеюсь, что упустил что-то очевидное. Я тестирую это на эмуляторе API 21.
Обновить
Я унаследовал часть этого кода. Возможно, что-то переопределяет настройку и переводит ее в режим LTR. Я сделал тестовое приложение, чтобы проверить режим RTL, и он работал нормально. Какой код может привести к тому, что параметр "Force RTL Layout Direction" будет проигнорирован (или переопределен)?
Обновление 2
Я проверил, что языковой стандарт устанавливается правильно, и это так. Я также проверил конфигурацию, и ldrtl
установлен. Я проверил в подписанном файле APK, что android:supportsRtl
сделал это и ни один из файлов макета не было android:layoutDirection="ltr"
. Я даже пытался вручную положить android:layoutDirection="rtl"
чтобы попытаться заставить макет зеркально android:layoutDirection="rtl"
, но это тоже не сработало. '
Обновление 3
Я добавил еще одно действие в проект, сделал его активностью запуска и убедился, что оно не связано с каким-либо существующим кодом. Это подкласс Activity
. Проблема все еще существует. Так что теоретически это проблема конфигурации. Как я уже сказал, я проверил файл AndroidManifest.xml и все файлы макетов, которые были сгенерированы, а также внесены изменения в поддержку RTL и макет. Что может быть не так с конфигурацией?
Ответы
Ответ 1
Самая неясная ошибка за всю историю. Как я уже упоминал в этом вопросе, большая часть этого кода была унаследована. В результате возникла проблема с побитовым оператором, которая портила флаги для приложения. &=
использовался вместо &
чтобы проверить, был ли установлен флаг.
Как отмечается в комментариях, код был взят из примера в блоге разработчиков Android, в котором объясняется, почему многие другие столкнулись с этой проблемой. Я подал отчет об ошибке, и с тех пор сообщение в блоге было тихо обновлено. Вот оригинальный код, который я удалил &=
. Не используйте следующий код как есть. Вам нужно изменить &=
на &
:
isDebuggable = (appContext.getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE) != 0;
Ответ 2
Попробуйте это...
-
Создайте класс для поддержания состояния глобального приложения.
public class YourGlobalClass extends Application {
@Override
public void onCreate() {
updateLanguage(this, null);
super.onCreate();
}
public static void updateLanguage(Context ctx, String lang) {
Configuration cfg = new Configuration();
LocalSharedManager manager = new LocalSharedManager(ctx);
String language = manager.GetValueFromSharedPrefs("force_locale");
if (TextUtils.isEmpty(language) && lang == null) {
cfg.locale = Locale.getDefault();
String tmp_locale = "";
tmp_locale = Locale.getDefault().toString().substring(0, 2);
manager.SaveValueToSharedPrefs("force_locale", tmp_locale);
} else if (lang != null) {
cfg.locale = new Locale(lang);
manager.SaveValueToSharedPrefs("force_locale", lang);
} else if (!TextUtils.isEmpty(language)) {
cfg.locale = new Locale(language);
}
ctx.getResources().updateConfiguration(cfg, null);
}
}
-
Укажите глобальный класс в тэг AndroidManifest.xml, который приведет к созданию экземпляра класса с сохраненной локалью, когда будет создан процесс для вашего приложения/пакета. Например, android:name="com.your.package.YourGlobalClass" android:supportsRtl="true"
-
Создайте следующие два метода в вашем MainActivity.java(где угодно).
public class MainActivity extends ActionBarActivity{
.......
// Implement OnclickListener for english_locale button
findViewById(R.id.english_locale).setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
changeEnglish();
}
});
// Implement OnclickListener for arabic_locale button
findViewById(R.id.arabic_locale).setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
changeArabic();
}
});
/**
* Method that Update UI for Arabic locale.
*/
public void changeArabic() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
String app_locale = "ar";
Locale locale = new Locale(app_locale);
Locale.setDefault(locale);
//Configuration to query the current layout direction.
Configuration config = new Configuration();
config.locale = locale;
getResources().updateConfiguration(config,
getResources().getDisplayMetrics());
Bidi bidi = new Bidi(app_locale,
Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
bidi.isRightToLeft();
YourGlobalClass.updateLanguage(getActivity(), "ar");
//Refreshing current fragment
Intent i = getActivity().getIntent();
startActivity(i);
getActivity().finish();
return null;
}
}.execute();
}
/**
* Method that Update UI for Default(English) locale.
*/
public void changeEnglish() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
String app_locale = "en";
Locale locale = new Locale(app_locale);
Locale.setDefault(locale);
//Configuration to query the current layout direction.
Configuration config = new Configuration();
config.locale = locale;
getResources().updateConfiguration(config,
getResources().getDisplayMetrics());
Bidi bidi = new Bidi(app_locale,
Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
bidi.isLeftToRight();
YourGlobalClass.updateLanguage(getActivity(), "en");
//Refreshing current fragment
Intent i = getActivity().getIntent();
startActivity(i);
getActivity().finish();
return null;
}
}.execute();
}
......
//MainActivity end
}
-
Счастливое кодирование...
Ответ 3
добавьте эту строку кода в самый верх метода onCreate (перед super и setContentView) всех ваших действий:
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
и убедитесь, что у вас supportRtl равен True в манифесте.
android:supportsRtl="true"