Meine App unterstützt 3 (bald 4) Sprachen. Da mehrere Gebietsschemas sehr ähnlich sind, möchte ich dem Benutzer die Möglichkeit geben, das Gebietsschema in meiner Anwendung zu ändern. Beispielsweise könnte eine italienische Person Spanisch gegenüber Englisch bevorzugen.
Gibt es eine Möglichkeit für den Benutzer, unter den für die Anwendung verfügbaren Gebietsschemas auszuwählen und dann zu ändern, welches Gebietsschema verwendet wird? Ich sehe es nicht als Problem an, das Gebietsschema für jede Aktivität festzulegen, da es eine einfache Aufgabe ist, die in einer Basisklasse ausgeführt wird.
android
locale
user-defined
Roland
quelle
quelle
Antworten:
Für Personen, die immer noch nach dieser Antwort suchen
configuration.locale
, können Sie jetzt Folgendes verwenden, da sie von API 24 nicht mehr unterstützt wird:Beachten Sie, dass die minSkdVersion für diese Methode API 17 ist.
Vollständiger Beispielcode:
Vergessen Sie nicht, dass Sie das Gebietsschema, wenn Sie eine laufende Aktivität ändern, neu starten müssen, damit die Änderungen wirksam werden.
BEARBEITEN 11. MAI 2018
Ab dem Beitrag von @ CookieMonster haben Sie möglicherweise Probleme, die Gebietsschemaänderung in höheren API-Versionen beizubehalten. Wenn ja, fügen Sie Ihrer Basisaktivität den folgenden Code hinzu, damit Sie das Kontextgebietsschema bei jeder Aktivitätserstellung aktualisieren:
Wenn Sie dies verwenden, vergessen Sie nicht, die Sprache in SharedPreferences zu speichern, wenn Sie das Gebietsschema mit festlegen
setLocate(locale)
EDIT 7. APRIL 2020
Möglicherweise treten Probleme in Android 6 und 7 auf. Dies liegt an einem Problem in den AndroidX-Bibliotheken, während der Nachtmodus ausgeführt wird. Dazu müssen Sie auch
applyOverrideConfiguration
Ihre Basisaktivität überschreiben und das Gebietsschema der Konfiguration aktualisieren, falls ein neues Gebietsschema erstellt wird.Beispielcode:
quelle
androidx.appcompat:appcompat:
Version von1.0.2
zu1.1.0
nicht auf Android 7 arbeiten, aber arbeitet an Android 9.1.1.0
Androidxappcompat:1.1.0
kann behoben werdenappcompat:1.2.0-alpha02
und Code imSet<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));
Inneren@TargetApi(Build.VERSION_CODES.N) updateResourcesLocale()
Hoffe diese Hilfe (in onResume):
quelle
Ich hatte ein Problem beim programmgesteuerten Festlegen des Gebietsschemas mit Geräten mit Android OS N und höher . Für mich bestand die Lösung darin, diesen Code in meine Basisaktivität zu schreiben:
(Wenn Sie keine Basisaktivität haben, sollten Sie diese Änderungen in all Ihren Aktivitäten vornehmen.)
Beachten Sie, dass es hier nicht ausreicht, anzurufen
Sie müssen auch den Kontext abrufen, den diese Methode zurückgibt, und diesen Kontext dann in der
attachBaseContext
Methode festlegen .quelle
updateBaseContextLocale
MethodeonCreate
Ihrer Eltern- / Basisaktivität auf.Da für den aktuellen Weg zur Lösung dieses Problems keine Antwort vollständig ist, versuche ich, Anweisungen für eine vollständige Lösung zu geben. Bitte kommentieren Sie, wenn etwas fehlt oder besser gemacht werden könnte.
Allgemeine Information
Erstens gibt es einige Bibliotheken, die das Problem lösen möchten, aber alle scheinen veraltet zu sein oder es fehlen einige Funktionen:
Außerdem denke ich, dass das Schreiben einer Bibliothek möglicherweise keine gute / einfache Möglichkeit ist, dieses Problem zu lösen, da nicht viel zu tun ist und der vorhandene Code eher geändert werden muss, als etwas vollständig Entkoppeltes zu verwenden. Deshalb habe ich die folgenden Anweisungen verfasst, die vollständig sein sollten.
Meine Lösung basiert hauptsächlich auf https://github.com/gunhansancar/ChangeLanguageExample (wie bereits von localhost verlinkt ). Es ist der beste Code, an dem ich mich orientieren konnte. Einige Anmerkungen:
updateViews()
In jeder Aktivität wird eine Methode verwendet , um alle Zeichenfolgen nach dem Ändern des Gebietsschemas (unter Verwendung des üblichengetString(id)
) manuell zu aktualisieren, was bei dem unten gezeigten Ansatz nicht erforderlich istIch habe es ein wenig geändert und den Teil entkoppelt, der das ausgewählte Gebietsschema beibehält (da man dies möglicherweise separat tun möchte, wie unten vorgeschlagen).
Lösung
Die Lösung besteht aus den folgenden zwei Schritten:
Schritt 1: Ändern Sie das Gebietsschema
Verwenden Sie die Klasse
LocaleHelper
, die auf gunhansancars LocaleHelper basiert :ListPreference
in aPreferenceFragment
mit den verfügbaren Sprachen hinzu (muss beibehalten werden, wenn Sprachen später hinzugefügt werden sollen)Erstellen Sie
SettingsFragment
wie folgt:Erstellen Sie eine Ressource,
locales.xml
in der alle Gebietsschemas mit verfügbaren Übersetzungen wie folgt aufgelistet sind ( Liste der Gebietsschemacodes ):In Ihrem können
PreferenceScreen
Sie den folgenden Abschnitt verwenden, damit der Benutzer die verfügbaren Sprachen auswählen kann:Dabei werden die folgenden Zeichenfolgen verwendet
strings.xml
:Schritt 2: Lassen Sie die App das benutzerdefinierte Gebietsschema verwenden
Richten Sie nun jede Aktivität so ein, dass das benutzerdefinierte Gebietsschemaset verwendet wird. Der einfachste Weg, dies zu erreichen, besteht darin, eine gemeinsame Basisklasse für alle Aktivitäten mit dem folgenden Code zu haben (wobei sich der wichtige Code in
attachBaseContext(Context base)
und befindetonResume()
):Was es tut ist
attachBaseContext(Context base)
, um das zuvor beibehaltene Gebietsschema zu verwendenLocaleHelper
Hinweise zu dieser Lösung
Durch das erneute Erstellen einer Aktivität wird der Titel der Aktionsleiste nicht aktualisiert (wie hier bereits erwähnt: https://github.com/gunhansancar/ChangeLanguageExample/issues/1 ).
setTitle(R.string.mytitle)
in demonCreate()
Verfahren jeder Aktivität.Hiermit kann der Benutzer das Standardgebietsschema des Systems sowie das Standardgebietsschema der App auswählen (das benannt werden kann, in diesem Fall "Englisch").
fr-rCA
Bisher werden nur Sprachcodes, keine Region (Land) und Variantencodes (wie ) unterstützt. Zur Unterstützung der vollständigen Gebietsschemaspezifikationen kann ein Parser verwendet werden, der dem in der Android-Languages-Bibliothek ähnelt (der Regions-, aber keine Variantencodes unterstützt).quelle
attachBaseContext(Context base)
undonResume()
in eine separate Klasse) kann den Trick tun. Dann müssen Sie nur noch ein Objekt in jeder Aktivitätsbasisklasse deklarieren und diese beiden Aufrufe delegieren.Verwenden Sie einfach diese Hilfsmethode, um ein bestimmtes Gebietsschema zu erzwingen.
UDPATE 22 AUG 2017. Verwenden Sie diesen Ansatz besser .
quelle
Fügen Sie eine Hilfsklasse mit der folgenden Methode hinzu:
Und nennen Sie es in Ihrer Startaktivität wie
MainActivity.java
:quelle
simpel und einfach
Dabei ist "en" der Sprachcode und "US" der Ländercode.
quelle
conf.locale=locale;
ist veraltet und ist es auchupdateConfiguration
.Gültig für API16 bis API28 Platzieren Sie diese Methode einfach an einer Stelle, an der:
Fügen Sie diesen Code in alle Ihre Aktivitäten ein, indem Sie:
oder rufen Sie localeUpdateResources für Fragmente, Adapter usw. auf, in denen Sie den neuen Kontext benötigen.
Credits: Jaroslaw Berezanskyi
quelle
Es gibt einen super einfachen Weg.
In BaseActivity überschreiben Activity oder Fragment attachBaseContext
Erweiterung
quelle
Ich fand den
androidx.appcompat:appcompat:1.1.0
Fehler kann auch einfach durch Aufruf fixiert werdengetResources()
inapplyOverrideConfiguration()
quelle
quelle
Für diejenigen, die alles versucht haben, aber nicht funktionieren . Bitte überprüfen Sie, dass , wenn Sie setzen
darkmode
mitAppCompatDelegate.setDefaultNightMode
und das System nicht dunkel ist, dannConfiguration.setLocale
wird nicht funktionieren über Andorid 7.0 .Fügen Sie diesen Code in jede Aktivität ein, um dieses Problem zu lösen:
quelle
Fügen Sie diesen Code in Ihre Aktivität ein
quelle