Мое приложение поддерживает 3 (скоро 4) языка. Поскольку несколько локалей очень похожи, я бы хотел, чтобы пользователь мог изменить локаль в моем приложении, например, итальянец может предпочесть испанский, а не английский.
Есть ли способ для пользователя выбрать один из языковых стандартов, доступных для приложения, а затем изменить используемый языковой стандарт? Я не вижу проблемы в настройке локали для каждого действия, поскольку это простая задача для базового класса.
android
locale
user-defined
Roland
источник
источник
Ответы:
Для тех, кто все еще ищет этот ответ, поскольку он
configuration.locale
был устаревшим из API 24, теперь вы можете использовать:Примите во внимание, что minSkdVersion для этого метода - API 17.
Полный пример кода:
Не забывайте, что если вы измените локаль с запущенным Activity, вам нужно будет перезапустить ее, чтобы изменения вступили в силу.
РЕДАКТИРОВАТЬ 11 мая 2018
Начиная с поста @ CookieMonster, у вас могут возникнуть проблемы с сохранением изменения локали в более высоких версиях API. Если это так, добавьте следующий код в базовую активность, чтобы обновлять локаль контекста при каждом создании операции:
Если вы используете это, не забудьте сохранить язык в SharedPreferences, когда вы устанавливаете локаль с
setLocate(locale)
РЕДАКТИРОВАТЬ 7-го АПРЕЛЯ 2020
Возможно, у вас проблемы с Android 6 и 7, и это происходит из-за проблем в библиотеках androidx при работе в ночном режиме. Для этого вам также потребуется переопределить
applyOverrideConfiguration
базовое действие и обновить языковой стандарт конфигурации в случае создания нового нового языкового стандарта.Образец кода:
источник
androidx.appcompat:appcompat:
версии от1.0.2
до1.1.0
не работает на Android 7, но работать на андроид 9.1.1.0
androidxappcompat:1.1.0
может быть исправлена с помощьюappcompat:1.2.0-alpha02
кода иSet<Locale> set = new LinkedHashSet<>(); // bring the target locale to the front of the list set.add(locale); LocaleList all = LocaleList.getDefault(); for (int i = 0; i < all.size(); i++) { // append other locales supported by the user set.add(all.get(i)); } Locale[] locales = set.toArray(new Locale[0]); configuration.setLocales(new LocaleList(locales));
внутри@TargetApi(Build.VERSION_CODES.N) updateResourcesLocale()
Надеюсь, что это поможет (в onResume):
источник
У меня была проблема с программной настройкой локали на устройствах с ОС Android N и выше . Для меня решением было написать этот код в моей основной деятельности:
(если у вас нет базовой активности, вы должны внести эти изменения во все ваши действия)
обратите внимание, что здесь не достаточно позвонить
вам также нужно получить контекст, который возвращает этот метод, а затем установить этот контекст в
attachBaseContext
методе.источник
updateBaseContextLocale
метод вonCreate
вашей родительской / основной деятельности.Поскольку пока нет полного ответа на текущий способ решения этой проблемы, я пытаюсь дать инструкции для полного решения. Пожалуйста, прокомментируйте, если что-то отсутствует или может быть сделано лучше.
Главная Информация
Во-первых, существуют некоторые библиотеки, которые хотят решить проблему, но все они кажутся устаревшими или не имеют некоторых функций:
Кроме того, я думаю, что написание библиотеки, возможно, не является хорошим / простым способом решения этой проблемы, потому что не так уж много нужно сделать, и что нужно сделать, это скорее изменить существующий код, чем использовать что-то полностью отделенное. Поэтому я составил следующие инструкции, которые должны быть завершены.
Мое решение в основном основано на https://github.com/gunhansancar/ChangeLanguageExample (как уже связано с localhost ). Это лучший код для поиска. Некоторые замечания:
updateViews()
в каждом действии, чтобы вручную обновить все строки после изменения локали (используя обычныйgetString(id)
), что не является необходимым в подходе, показанном нижеЯ немного изменил его, отделив часть, которая сохраняет выбранную локаль (как можно было бы сделать это отдельно, как предложено ниже).
Решение
Решение состоит из следующих двух шагов:
Шаг 1: Измените локаль
Используйте класс
LocaleHelper
, основанный на LocaleHelper от gunhansancar :ListPreference
вPreferenceFragment
с доступными языками (необходимо сохранить, когда языки должны быть добавлены позже)Создайте
SettingsFragment
подобное:Создайте ресурс со
locales.xml
списком всех локалей с доступными переводами следующим образом ( список кодов локали ):В вашем
PreferenceScreen
разделе вы можете использовать следующий раздел, чтобы позволить пользователю выбирать доступные языки:который использует следующие строки из
strings.xml
:Шаг 2. Заставьте приложение использовать пользовательский язык
Теперь настройте каждое действие, чтобы использовать пользовательский набор языковых стандартов. Самый простой способ сделать это - иметь общий базовый класс для всех действий со следующим кодом (где находится важный код
attachBaseContext(Context base)
иonResume()
):Что это делает
attachBaseContext(Context base)
чтобы использовать локаль, ранее сохраненную сLocaleHelper
Примечания к этому решению
Воссоздание Действия не обновляет заголовок ActionBar (как уже наблюдалось здесь: https://github.com/gunhansancar/ChangeLanguageExample/issues/1 ).
setTitle(R.string.mytitle)
вonCreate()
методе каждого действия.Это позволяет пользователю выбрать системный языковой стандарт по умолчанию, а также языковой стандарт приложения по умолчанию (который может быть назван, в данном случае «английский»).
fr-rCA
Пока поддерживаются только языковые коды, ни регион (страна), ни коды вариантов (например ). Для поддержки полных спецификаций локали можно использовать синтаксический анализатор, подобный таковому в библиотеке Android-Languages (который поддерживает регион, но без кодов вариантов).источник
attachBaseContext(Context base)
иonResume()
в отдельный класс) может помочь. Затем все, что вам нужно сделать, это объявить один объект в каждом базовом классе активности и делегировать эти два вызова.Просто используйте этот вспомогательный метод для принудительного определения конкретной локали.
UDPATE 22 августа 2017 года. Лучше использовать этот подход .
источник
Добавьте вспомогательный класс с помощью следующего метода:
И назовите это в своей деятельности запуска, как
MainActivity.java
:источник
просто и легко
где «en» - это код языка, а «US» - код страны.
источник
conf.locale=locale;
не рекомендуется, а также являетсяupdateConfiguration
.Действительно от API16 до API28. Просто поместите этот метод где-нибудь:
Вставьте этот код во все ваши действия, используя:
или вызовите localeUpdateResources для фрагментов, адаптеров и т. д., где вам нужен новый контекст.
Кредиты: Ярослав Березанский
источник
Есть супер простой способ.
в BaseActivity, Activity или Fragment переопределить attachBaseContext
расширение
источник
Я обнаружил, что
androidx.appcompat:appcompat:1.1.0
ошибку можно исправить, просто позвонивgetResources()
вapplyOverrideConfiguration()
источник
источник
Для тех, кто все пробовал, но не работает . Пожалуйста, проверьте, что если вы установили
darkmode
с помощью,AppCompatDelegate.setDefaultNightMode
и система не темно, тоConfiguration.setLocale
не будет работать выше Andorid 7.0 .Добавьте этот код в каждое действие, чтобы решить эту проблему:
источник
Поместите этот код в вашу деятельность
источник