Moja aplikacja obsługuje 3 (wkrótce 4) języki. Ponieważ kilka języków jest dość podobnych, chciałbym dać użytkownikowi możliwość zmiany lokalizacji w mojej aplikacji, na przykład osoba z Włoch może preferować hiszpański od angielskiego.
Czy użytkownik może wybrać spośród ustawień regionalnych dostępnych dla aplikacji, a następnie zmienić używane ustawienia regionalne? Nie widzę problemu w ustawianiu ustawień regionalnych dla każdego działania, ponieważ jest to proste zadanie do wykonania w klasie bazowej.
android
locale
user-defined
Roland
źródło
źródło
Odpowiedzi:
Osoby, które nadal szukają tej odpowiedzi, ponieważ
configuration.locale
zostały wycofane z API 24, mogą teraz użyć:Weź pod uwagę, że minSkdVersion dla tej metody to API 17.
Pełny przykładowy kod:
Nie zapominaj, że jeśli zmienisz ustawienia regionalne za pomocą uruchomionego działania, będziesz musiał je ponownie uruchomić, aby zmiany odniosły skutek.
EDYCJA 11 MAJA 2018
Jak wynika z posta @ CookieMonster, możesz mieć problemy z utrzymaniem zmiany ustawień regionalnych w wyższych wersjach API. Jeśli tak, dodaj następujący kod do działania podstawowego, aby zaktualizować ustawienia regionalne kontekstu przy każdym utworzeniu działania:
Jeśli tego używasz, nie zapomnij zapisać języka w SharedPreferences podczas ustawiania ustawień regionalnych za pomocą
setLocate(locale)
EDYCJA 7 KWIETNIA 2020
Mogą występować problemy w systemie Android 6 i 7, a dzieje się tak z powodu problemu w bibliotekach systemu Androidx podczas obsługi trybu nocnego. W tym celu będziesz musiał również nadpisać
applyOverrideConfiguration
swoje podstawowe działanie i zaktualizować ustawienia regionalne konfiguracji w przypadku utworzenia nowego nowego ustawienia regionalnego.Przykładowy kod:
źródło
androidx.appcompat:appcompat:
wersji z1.0.2
na1.1.0
nie działa na Androidzie 7, ale działa na Androidzie 9.1.1.0
androidxaappcompat:1.1.0
można rozwiązaćappcompat:1.2.0-alpha02
i zakodować wSet<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));
środku@TargetApi(Build.VERSION_CODES.N) updateResourcesLocale()
Mam nadzieję, że ta pomoc (w onResume):
źródło
Miałem problem z programowym ustawieniem lokalizacji na urządzeniach z systemem Android OS N i nowszym . Dla mnie rozwiązaniem było napisanie tego kodu w mojej podstawowej aktywności:
(jeśli nie masz podstawowej aktywności, powinieneś wprowadzić te zmiany we wszystkich swoich działaniach)
zwróć uwagę, że tutaj nie wystarczy zadzwonić
musisz również pobrać kontekst, który zwraca ta metoda, a następnie ustawić ten kontekst w
attachBaseContext
metodzie.źródło
updateBaseContextLocale
metodę wonCreate
aktywności rodzica / podstawowej.Ponieważ nie ma pełnej odpowiedzi na temat obecnego sposobu rozwiązania tego problemu, staram się podać instrukcje dotyczące pełnego rozwiązania. Prosimy o komentarz, jeśli czegoś brakuje lub można to zrobić lepiej.
Informacje ogólne
Po pierwsze, istnieją biblioteki, które chcą rozwiązać ten problem, ale wszystkie wydają się przestarzałe lub brakuje im niektórych funkcji:
Ponadto myślę, że pisanie biblioteki może nie być dobrym / łatwym sposobem rozwiązania tego problemu, ponieważ nie ma zbyt wiele do zrobienia, a to, co należy zrobić, to raczej zmiana istniejącego kodu niż użycie czegoś całkowicie oddzielonego. Dlatego ułożyłem następujące instrukcje, które powinny być kompletne.
Moje rozwiązanie opiera się głównie na https://github.com/gunhansancar/ChangeLanguageExample (jak już jest połączone przez localhost ). To najlepszy kod, jaki znalazłem. Kilka uwag:
updateViews()
w każdym działaniu, aby ręcznie zaktualizować wszystkie ciągi znaków po zmianie ustawień regionalnych (używając zwykłychgetString(id)
), co nie jest konieczne w podejściu pokazanym poniżejZmieniłem to trochę, odsprzęgając część, która utrzymuje się w wybranym locale (jak można to zrobić osobno, jak zasugerowano poniżej).
Rozwiązanie
Rozwiązanie składa się z dwóch następujących kroków:
Krok 1: Zmień ustawienia regionalne
Użyj klasy
LocaleHelper
opartej na LocaleHelper firmy gunhansancar :ListPreference
w aPreferenceFragment
z dostępnymi językami (należy zachować, gdy języki mają być dodane później)Utwórz
SettingsFragment
podobny następujący:Utwórz zasób
locales.xml
wymieniający wszystkie języki z dostępnymi tłumaczeniami w następujący sposób ( lista kodów regionalnych ):W swoim
PreferenceScreen
możesz skorzystać z następującej sekcji, aby pozwolić użytkownikowi wybrać dostępne języki:który używa następujących ciągów z
strings.xml
:Krok 2: spraw, aby aplikacja korzystała z niestandardowych ustawień regionalnych
Teraz skonfiguruj każde działanie, aby korzystało z niestandardowego zestawu ustawień regionalnych. Najłatwiejszym sposobem osiągnięcia tego jest posiadanie wspólnej klasy bazowej dla wszystkich działań z następującym kodem (gdzie ważny kod znajduje się w
attachBaseContext(Context base)
ionResume()
):Co to jest
attachBaseContext(Context base)
aby użyć ustawień regionalnych, które zostały wcześniej utrwaloneLocaleHelper
Uwagi dotyczące tego rozwiązania
Odtworzenie działania nie aktualizuje tytułu ActionBar (jak już zauważono tutaj: https://github.com/gunhansancar/ChangeLanguageExample/issues/1 ).
setTitle(R.string.mytitle)
wonCreate()
metodzie każdej czynności.Pozwala użytkownikowi wybrać domyślne ustawienia regionalne systemu, a także domyślne ustawienia regionalne aplikacji (które można nazwać w tym przypadku „angielskim”).
Do
fr-rCA
tej pory obsługiwane są tylko kody języków, brak kodów regionu (kraju) i wariantów (takich jak ). Aby obsługiwać pełne specyfikacje regionalne, można użyć parsera podobnego do tego w bibliotece Android-Languages (który obsługuje region, ale nie obsługuje kodów wariantów).źródło
attachBaseContext(Context base)
ionResume()
do osobnej klasy) daje rade. Następnie wszystko, co musisz zrobić, to zadeklarować jeden obiekt w każdej klasie bazowej działania i delegować te dwa wywołania.Po prostu użyj tej metody pomocniczej, aby wymusić określone ustawienia regionalne.
UDPATE 22 sierpnia 2017. Lepiej wykorzystaj to podejście .
źródło
Dodaj klasę pomocniczą za pomocą następującej metody:
I nazwij to w swojej działalności startowej, na przykład
MainActivity.java
:źródło
proste i łatwe
gdzie „en” to kod języka, a „US” to kod kraju.
źródło
conf.locale=locale;
jest przestarzały, a także jestupdateConfiguration
.Obowiązuje dla API16 do API28 Po prostu umieść tę metodę w miejscu:
Wstaw ten kod we wszystkich swoich działaniach za pomocą:
lub wywołaj localeUpdateResources na fragmentach, adapterach itp. tam, gdzie potrzebujesz nowego kontekstu.
Kredyty: Yaroslav Berezanskyi
źródło
Jest super prosty sposób.
w BaseActivity, Activity lub Fragment przesłania attachBaseContext
rozbudowa
źródło
Uważam, że
androidx.appcompat:appcompat:1.1.0
błąd może być również ustalona po prostu przez wywołaniegetResources()
wapplyOverrideConfiguration()
źródło
źródło
Dla tych, którzy próbowali wszystkiego, ale nie działali . Proszę sprawdzić, czy ustawienie
darkmode
zAppCompatDelegate.setDefaultNightMode
a system nie jest ciemno, toConfiguration.setLocale
nie będzie działać powyżej Andorid 7.0 .Dodaj ten kod do każdego działania, aby rozwiązać ten problem:
źródło
Umieść ten kod w swojej aktywności
źródło