Moi użytkownicy mogą zmieniać ustawienia regionalne w aplikacji (mogą chcieć zachować ustawienia telefonu w języku angielskim, ale czytać zawartość mojej aplikacji w języku francuskim, holenderskim lub innym języku ...)
Dlaczego działa to doskonale w wersji 1.5 / 1.6, ale NIE w wersji 2.0?
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case 201:
Locale locale2 = new Locale("fr");
Locale.setDefault(locale2);
Configuration config2 = new Configuration();
config2.locale = locale2;
getBaseContext().getResources().updateConfiguration(
config2, getBaseContext().getResources().getDisplayMetrics());
// loading data ...
refresh();
// refresh the tabs and their content
refresh_Tab ();
break;
case 201: etc...
Problem polega na tym, że MENU „kurczy się” coraz bardziej za każdym razem, gdy użytkownik przechodzi przez linie kodu powyżej ...
To menu się kurczy:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 100, 1, "REFRESH").setIcon(android.R.drawable.ic_menu_compass);
SubMenu langMenu = menu.addSubMenu(0, 200, 2, "NL-FR").setIcon(android.R.drawable.ic_menu_rotate);
langMenu.add(1, 201, 0, "Nederlands");
langMenu.add(1, 202, 0, "Français");
menu.add(0, 250, 4, R.string.OptionMenu2).setIcon(android.R.drawable.ic_menu_send);
menu.add(0, 300, 5, R.string.OptionMenu3).setIcon(android.R.drawable.ic_menu_preferences);
menu.add(0, 350, 3, R.string.OptionMenu4).setIcon(android.R.drawable.ic_menu_more);
menu.add(0, 400, 6, "Exit").setIcon(android.R.drawable.ic_menu_delete);
return super.onCreateOptionsMenu(menu);
}
Co powinienem zrobić na poziomie API 5, aby znów działało?
TU JEST PEŁNY KOD, JEŚLI CHCESZ TESTOWAĆ TO:
import java.util.Locale;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.widget.Toast;
public class Main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
SubMenu langMenu = menu.addSubMenu(0, 200, 2, "NL-FR").setIcon(android.R.drawable.ic_menu_rotate);
langMenu.add(1, 201, 0, "Nederlands");
langMenu.add(1, 202, 0, "Français");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case 201:
Locale locale = new Locale("nl");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
Toast.makeText(this, "Locale in Nederlands !", Toast.LENGTH_LONG).show();
break;
case 202:
Locale locale2 = new Locale("fr");
Locale.setDefault(locale2);
Configuration config2 = new Configuration();
config2.locale = locale2;
getBaseContext().getResources().updateConfiguration(config2, getBaseContext().getResources().getDisplayMetrics());
Toast.makeText(this, "Locale en Français !", Toast.LENGTH_LONG).show();
break;
}
return super.onOptionsItemSelected(item);
}
}
I TU JEST MANIFEST:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cousinHub.ChangeLocale"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Main"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>
TO ZNALEZIONO:
<uses-sdk android:minSdkVersion="5" />
=> TO DZIAŁA WŁAŚNIE DOBRA ...
<uses-sdk android:minSdkVersion="3" />
=> Menu kurczy się przy każdej zmianie ustawień regionalnych !!!
ponieważ chcę, aby moja aplikacja była dostępna dla użytkowników w wersji 1.5, co powinienem zrobić?
Odpowiedzi:
W oryginalnym pytaniu nie chodzi o samą lokalizację, wszystkie inne pytania dotyczące tej lokalizacji odnoszą się do tego pytania. Dlatego chciałem tutaj wyjaśnić tę kwestię. Użyłem tego pytania jako punktu wyjścia dla mojego własnego kodu zmiany ustawień regionalnych i odkryłem, że metoda nie jest dokładnie poprawna. Działa, ale tylko do czasu zmiany konfiguracji (np. Obrót ekranu) i tylko w tej konkretnej czynności. Przez jakiś czas bawiłem się kodem i skończyłem na następującym podejściu:
Rozszerzyłem aplikację android.app.Application i dodałem następujący kod:
Ten kod zapewnia, że każde działanie będzie mieć ustawione niestandardowe ustawienia narodowe i nie zostanie zresetowane po rotacji i innych zdarzeniach.
Spędziłem również dużo czasu, próbując wprowadzić zmiany preferencji, aby zostały zastosowane natychmiast, ale nie powiodło się: język zmienił się poprawnie po ponownym uruchomieniu działania, ale formaty liczb i inne właściwości ustawień narodowych nie zostały zastosowane aż do pełnego ponownego uruchomienia aplikacji.
Zmiany w
AndroidManifest.xml
Nie zapomnij dodać
android:configChanges="layoutDirection|locale"
do każdej aktywności w AndroidManifest, a takżeandroid:name=".MyApplication"
do<application>
elementu.źródło
config
inewConfig
).config = new Configuration(config);
Najpierw powinieneś wykonać kopię . Właśnie spędziłem godzinę debugując ten kod, zanim odkryłem problem (powodował niekończące się flashowanie działania).updateConfiguration()
działania, więc czasami Twoja aktywność będzie wyświetlana w 2 różnych językach (szczególnie w oknach dialogowych). Więcej informacji: stackoverflow.com/questions/39705739/…Po dobrze przespanej nocy znalazłem odpowiedź w Internecie (proste wyszukiwanie w Google w następującym wierszu „
getBaseContext().getResources().updateConfiguration(mConfig, getBaseContext().getResources().getDisplayMetrics());
”), oto ona:link text => ten link pokazuje także,
screenshots
co się dzieje!Problemem była gęstość , musiałem to mieć w pliku AndroidManifest.xml
Najważniejszy jest android: anyDensity = "true" .
Nie zapomnij dodać następujących elementów
AndroidManifest.xml
do każdego działania (dla Androida 4.1 i niższych):Ta wersja jest potrzebna, gdy budujesz dla Androida 4.2 (API poziom 17) wyjaśnienie tutaj :
źródło
activity.recreate()
W Androidzie M najlepsze rozwiązanie nie działa. Napisałem klasę pomocnika, aby naprawić to, co powinieneś wywołać z klasy aplikacji i wszystkich działań (sugerowałbym utworzenie BaseActivity, a następnie sprawienie, by wszystkie działania dziedziczyły po niej).
Uwaga : Będzie to również obsługiwać poprawnie kierunek układu RTL.
Klasa pomocnicza:
Podanie:
BaseActivity:
źródło
BaseActivity()
konstruktor nie powinien zadzwonićsuper()
?<application android:name=".App">
manifestu? Co powiesz na dodanieandroid:configChanges="layoutDirection|locale"
do każdej aktywności w manifeście?To jest mój komentarz do odpowiedzi Andreya, ale nie mogę dołączyć kodu w komentarzach.
Czy preferujesz aktywność wywoływaną z głównej aktywności? możesz umieścić to w CV ...
źródło
activity.recreate()
recreate()
metodę, więc użyjrecreate()
zamiastrefresh()
w kodzie. Spowoduje to zapisanie 3 wiersza kodu wrefresh()
metodzieNie mogłem użyć Androida: anyDensity = "true", ponieważ obiekty w mojej grze byłyby ustawione zupełnie inaczej ... wygląda na to, że to działa:
źródło
code Locale.setDefault(mLocale); Configuration config = getBaseContext().getResources().getConfiguration(); if (!config.locale.equals(mLocale)) { config.locale = mLocale; getBaseContext().getResources().updateConfiguration(config, null); }
Jeśli chcesz wpłynąć na opcje menu umożliwiające natychmiastową zmianę ustawień regionalnych, musisz to zrobić.
źródło
onMenuOpened
należy wywołać tylko raz, po zmianie ustawień regionalnych.