Wechseln Sie die Sprache in der Android App


Es gibt eine einfache Möglichkeit, die Sprachumschaltung in einer Einzelaktivitätsanwendung zu implementieren. Der Stapel von Bildschirmen in diesem Ansatz wird nicht zurückgesetzt, der Benutzer bleibt dort, wo er die Sprache gewechselt hat. Wenn der Benutzer zu vorherigen Bildschirmen wechselt, werden diese sofort übersetzt angezeigt. Und das Ergebnis der Lokalisierung von Zahlen, Geldsummen und Zinsen kann Designer überraschen.


Hebrew, motherfucker! Do you speak it?!


Was wird besprochen und was nicht?


Weiter wird es nichts geben über:


  • Die Theorie , die der formatierten Ausgabe von Zeichenfolgen zugrunde liegt, und die Implementierungsdetails der Bibliotheken, die sich damit befassen. Das ist etwas, das Ihnen beim Schreiben Ihrer Bibliothek helfen würde.
  • Ressourcenzeichenfolge , Vektor und andere. Informationen darüber, welche Ressourcenqualifizierer verwendet werden sollen, welche Bilder auf Arabisch von rechts nach links angezeigt werden sollen und welche nicht, und andere Feinheiten.
  • Der Prozess der zentralisierten Übersetzung von Ressourcen für alle Plattformen. Wie man es so organisiert, dass jeder gut lebt, auch iOS-Spitznamen.

Und wir werden reden über:


  • Übe. Betrachten Sie das Problem, seine Einschränkungen und seine Lösung mit Diagrammen, Beispielen und Codefragmenten.
  • Die SDK-API , die für diese Lösung verwendet wurde.
  • Merkmale der Formatierung numerischer Werte für verschiedene regionale Standards, über die Designer Bescheid wissen sollten.

Was wollen wir machen


Lassen Sie es einen Bildschirm mit Einstellungen in unserer Anwendung geben, und wir möchten ein paar neue Elemente hinzufügen, von denen eines es Ihnen ermöglicht, die Sprache der Anwendung zu wechseln, und das andere, die Währung zu ändern, in der die Geldbeträge angezeigt werden. Hier sind einige Beispiele, wie dies aussehen könnte.


Telegram.  .


Telegram.  .


Diese Einstellungen sollten nicht nur den Text übersetzen und das Layout von rechts nach links anzeigen, sondern auch das Format für die Anzeige numerischer Werte beeinflussen. Es ist erforderlich, dass alles entsprechend dem ausgewählten Gebietsschema angezeigt wird.


.


Architektonische Lösung


Stellen Sie sich vor, unsere Bewerbung wurde gemäß dem Single-Activity-Ansatz verfasst . Dann kann der Sprachumschaltmechanismus wie folgt implementiert werden.


.


SettingsInteractor ist die Quelle des aktuellen Sprachwerts. Sie können diesen Wert abonnieren, synchron empfangen und nur Updates abonnieren. Bei Bedarf können Sie eine zusätzliche Abstraktion über SettingsInteractor nach dem Prinzip der Schnittstellentrennung einführen. Im Diagramm werden irrelevante Details weggelassen.


AppActivity bei der Erstellung ersetzt den Kontext durch einen neuen, sodass die Anwendung Ressourcen für die ausgewählte Sprache verwendet.


 override fun attachBaseContext(base: Context) { super.attachBaseContext(applySelectedAppLanguage(base)) } private fun applySelectedAppLanguage(context: Context): Context { val locale = settingsInteractor.getUserSelectedLanguageBlocking() val newConfig = Configuration(context.resources.configuration) Locale.setDefault(locale) newConfig.setLocale(locale) return context.createConfigurationContext(newConfig) } 

AppPresenter abonniert wiederum AppPresenter und benachrichtigt View über die Änderungen.


 override fun onFirstViewAttach() { super.onFirstViewAttach() subscribeToLanguageUpdates() } private fun subscribeToLanguageUpdates() { settingsInteractor .getUserSelectedLanguageUpdates() .subscribe( { newLang -> viewState.applyNewAppLanguage(newLang) }, { error -> errorHandler.handle(error) } ) .disposeOnDestroy() } 

AppActivity neu erstellt, wenn eine Benachrichtigung über eine AppActivity .


 override fun applyNewAppLanguage(lang: Locale) = recreate() 

.


AppActivity ist die einzige in der Anwendung. Alle anderen Bildschirme sind in Fragmenten implementiert. Daher wird beim Neuerstellen der Aktivität der Bildschirmstapel vom System gespeichert. Wenn Sie zu den vorherigen Bildschirmen zurückkehren, werden diese neu initialisiert und übersetzt angezeigt. Der Benutzer bleibt in der Sprachauswahlliste und sieht sofort das Ergebnis seiner Wahl.


Formatieren von Zahlen, Bargeld und Zinsen


Zusätzlich zum Ersetzen des Kontexts müssen die Daten formatiert werden - Zahlen, Geld, Zinsen. Lassen Sie jede Ansicht diese Aufgabe an eine separate Komponente delegieren, nennen wir sie UiLocalizer .


UiLocalizer.


UiLocalizer verwendet die entsprechenden NumberFormat Instanzen, um eine Zahl in eine Zeichenfolge zu konvertieren.


 private var numberFormat = NumberFormat.getNumberInstance(lang) private var percentFormat = NumberFormat.getPercentInstance(lang) private fun getNumberFormatForCurrency(currency: Currency) = NumberFormat .getCurrencyInstance(lang) .also { it.currency = currency } 

Bitte beachten Sie, dass die Währung separat eingestellt werden muss.


Wenn Sie CPU-Zyklen und Speicherbits sparen und das Wechseln von Währung und Sprache die wichtigste und häufig verwendete Funktion Ihrer Anwendung ist, benötigen Sie natürlich einen Cache.


Darstellung von Sprachen und Währungen


Instanzen der Locale Klasse werden durch ein Sprach-Tag erstellt , das aus einem aus zwei Buchstaben bestehenden Sprachcode und einem aus zwei Buchstaben bestehenden Regionscode besteht. Instanzen der Currency Klasse basieren auf einem dreistelligen ISO-Code . In diesem Formular müssen Sprache und Währung serialisiert werden, um auf der Festplatte gespeichert oder über das Netzwerk übertragen zu werden. Dann ist es gut. Hier sind einige Beispiele.


 // IETF BCP 47 language tag string. private val langs = arrayOf( Locale.forLanguageTag("ru-RU"), Locale.forLanguageTag("en-US"), Locale.forLanguageTag("en-GB"), Locale.forLanguageTag("he-IL"), Locale.forLanguageTag("ar-SA"), Locale.forLanguageTag("ar-AE"), Locale.forLanguageTag("fr-FR"), Locale.forLanguageTag("fr-CH"), Locale.forLanguageTag("de-DE"), Locale.forLanguageTag("de-CH"), Locale.forLanguageTag("da-DK") ) // ISO 4217 code of the currency. private val currencies = arrayListOf( Currency.getInstance("RUB"), Currency.getInstance("USD"), Currency.getInstance("GBP"), Currency.getInstance("ILS"), Currency.getInstance("SAR"), Currency.getInstance("AED"), Currency.getInstance("EUR"), Currency.getInstance("CHF"), Currency.getInstance("DKK") ) 

Funktionen zum Formatieren numerischer Werte


Das Ergebnis der Formatierung von Nummern gemäß regionalen Standards kann von den Erwartungen abweichen. Das Währungssymbol oder sein dreistelliger Code in verschiedenen Sprachen wird auf unterschiedliche Weise angezeigt. Minuszeichen für negative Geldwerte werden an unerwarteten Stellen angezeigt, und an einigen Stellen werden stattdessen Klammern angezeigt. Das Prozentzeichen ist möglicherweise nicht genau das Zeichen, an das wir gewöhnt sind.


Tatsache ist, dass aus Sicht der regionalen Muster die letzte Zeile aus einem Präfix und einem Suffix für positive und negative Zahlen, einem Tausendertrennzeichen und einem Dezimaltrennzeichen besteht und für verschiedene Gebietsschemata unterschiedlich ist.


Die Zahlen


SpracheNegatives PräfixNegatives SuffixPositives PräfixPositives SuffixGruppierung sepaaratorDezimaltrennzeichen
ru-RU"-"""","
en-US"-"",""."
iw-IL"-"",""."
ar-AE"-""٬""٫"
fr-FR"-"""","
de-de"-""."","
de-CH"-""'""."
da-dk"-""."","

Währungen


SpracheNegatives PräfixNegatives SuffixPositives PräfixPositives SuffixGruppierung sepaaratorDezimaltrennzeichen
ru-RU"-""₽""₽"""","
en-US"- $""$"",""."
iw-IL"-""₪""₪"",""."
ar-AE"-""د.إ.""د.إ.""٬""٫"
fr-FR"-""€""€"""","
de-de"-""€""€""."","
de-CH"CHF-"CHF"'""."
da-dk"-""kr.""kr.""."","

Interesse


SpracheNegatives PräfixNegatives SuffixPositives PräfixPositives SuffixGruppierung sepaaratorDezimaltrennzeichen
ru-RU"-""%""%"""","
en-US"-""%""%"",""."
iw-IL"-""%""%"",""."
ar-AE"-""٪""٪""٬""٫"
fr-FR"-""%""%"""","
de-de"-""%""%""."","
de-CH"-""%""%""'""."
da-dk"-""%""%""."","

Darüber hinaus können die Formatierungsergebnisse für Android SDK und JDK unterschiedlich sein. Darüber hinaus sind alle Optionen korrekt und werden jeweils in bestimmten Kontexten verwendet.


Android  JDK.


Dezimalformat


Wenn wir ein NumberFormat erstellen, um bestimmte Werte zu formatieren, erhalten wir Objekte der DecimalFormat Klasse, die einfach von verschiedenen Vorlagen konfiguriert werden. Indem Sie DecimalFormat Objekt in den DecimalFormat Typ DecimalFormat und dessen Schnittstelle verwenden, können Sie Teile der Vorlage ändern, um alles zu DecimalFormat . Aber es ist besser, Gegebenheit anzubeten.


DecimalFormat.


Sie können auch einen Test schreiben, um die Vielfalt zu genießen. Nicht für alle Ländereinstellungen wird dieselbe Währung mit einem Symbol angezeigt.


.


Zusammenfassend


Das allgemeine Schema der Lösung ist wie folgt.


.


Der AppActivity Lebenszyklus ist der Lebenszyklus der gesamten Anwendung. Daher reicht es aus, es neu zu erstellen, um die gesamte Anwendung neu zu starten und die ausgewählte Sprache anzuwenden. Und da es nur eine Aktivität gibt, reicht es aus, das Abonnement zum Ändern der Sprache an einem Ort zu behalten - in AppPresenter .


Wie wir gesehen haben, sind regionale Formate für die Ausgabe von Zahlen nicht trivial. Sie sollten nicht für alle Gelegenheiten eine einzige Vorlage festlegen. Es ist besser, die Formatierung des SDK anzuvertrauen und zuzustimmen, dass die Zahlen gemäß dem Standard angezeigt werden und nicht wie in den Layouts angegeben.


Was ist einfacher zu testen? (Bonus)


Um Zeit zu sparen, können Sie das folgende Flag verwenden.


 android { ... buildTypes { debug { pseudoLocalesEnabled true } } ... } 

Wählen Sie in den Telefoneinstellungen das gewünschte Pseudo-Gebietsschema aus


.


Beobachten Sie, wie das Layout aufgrund des langen Textes abläuft und einige Elemente der Benutzeroberfläche hartnäckig nicht von rechts nach links angezeigt werden möchten.


.


Weitere Informationen finden Sie in der Dokumentation .


Es ist erwähnenswert, dass Pseudo-Gebietsschemas nicht funktionieren, wenn Sie den Kontext wie in der obigen Lösung ändern. Sie ändern den Kontext. Daher müssen Sie der Sprachauswahlliste in der Anwendung en-XA und ar-XB hinzufügen.


Das ist alles. Gute Lokalisierung und gute Laune!


Thanks

Source: https://habr.com/ru/post/de461085/


All Articles