Zmiana ustawień regionalnych w samej aplikacji
Moi użytkownicy mogą zmienić ustawienia regionalne w aplikacji (mogą chcieć zachować ustawienia telefonu w języku Angielskim, ale czytać zawartość mojej aplikacji w języku francuskim, holenderskim lub dowolnym innym języku ...)
Dlaczego to działa idealnie w 1.5/1.6, ale nie w 2.0 już ???
@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 powyższe linie kodu ...
To jest Menu, które 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 to znowu zadziałało ?
OTO PEŁNY KOD, JEŚLI CHCESZ TO PRZETESTOWAĆ:
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);
}
}
A OTO 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>
OTO CO ZNALAZŁEM:
<uses-sdk android:minSdkVersion="5" />
= > TO DZIAŁA DOBRZE ...
<uses-sdk android:minSdkVersion="3" />
= > Menu kurczy się za każdym razem, gdy zmienisz ustawienia regionalne !!!
Ponieważ chcę, aby moja aplikacja była dostępna dla użytkowników w wersji 1.5, co powinienem zrobić ??
6 answers
Przez oryginalne pytanie nie jest dokładnie o samym locale wszystkie inne pytania związane z locale odnoszą się do tego. Dlatego chciałem wyjaśnić tę kwestię tutaj. Użyłem tego pytania jako punktu wyjścia dla mojego własnego kodu przełączania locale i dowiedziałem się, że metoda nie jest dokładnie poprawna. Działa, ale tylko do zmiany konfiguracji (np. obrót ekranu) i tylko w tej konkretnej czynności. Zabawa z kodem przez jakiś czas skończyło się na następujących podejście:
Mam Rozszerzony android.app.Wniosek i dodano następujący kod:
public class MyApplication extends Application
{
private Locale locale = null;
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
if (locale != null)
{
newConfig.locale = locale;
Locale.setDefault(locale);
getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
}
}
@Override
public void onCreate()
{
super.onCreate();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
Configuration config = getBaseContext().getResources().getConfiguration();
String lang = settings.getString(getString(R.string.pref_locale), "");
if (! "".equals(lang) && ! config.locale.getLanguage().equals(lang))
{
locale = new Locale(lang);
Locale.setDefault(locale);
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
}
}
Ten kod zapewnia, że każda aktywność będzie miała własne ustawienia regionalne i nie będzie resetowana przy rotacji i innych zdarzeniach.
Spędziłem również dużo czasu próbując wprowadzić zmianę preferencji natychmiast, ale nie udało się: język zmienił się poprawnie po ponownym uruchomieniu aktywności, ale formaty liczb i inne właściwości locale nie zostały zastosowane do pełnego zastosowania uruchom ponownie.
Zmiany na AndroidManifest.xml
Nie zapomnij dodać android:configChanges="layoutDirection|locale"
do każdej aktywności na AndroidManifest, a także android:name=".MyApplication"
do elementu <application>
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-03 16:04:39
Po dobrej nocy snu, znalazłem odpowiedź w Internecie (proste wyszukiwanie Google w następującej linii " getBaseContext().getResources().updateConfiguration(mConfig, getBaseContext().getResources().getDisplayMetrics());
"), oto jest:
Link text
= > ten link pokazuje również screenshots
tego, co się dzieje !
Gęstość była problemem tutaj , musiałem mieć to w AndroidManifest.xml
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true"
/>
Najważniejszy jest android: anyDensity = "true" .
Nie zapomnij dodać w AndroidManifest.xml
do każdej aktywności (dla Android 4.1 i poniżej):
android:configChanges="locale"
Ta wersja jest potrzebna podczas tworzenia dla Androida 4.2 (poziom API 17) Wyjaśnienie tutaj :
android:configChanges="locale|layoutDirection"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:26
W Androidzie m najlepsze rozwiązanie nie będzie działać. Napisałem klasę pomocniczą, aby naprawić to, co powinieneś wywołać z klasy aplikacji i wszystkich działań (sugerowałbym utworzenie BaseActivity, a następnie sprawić, aby wszystkie działania dziedziczyły z niej.
Uwaga: będzie to również poprawnie obsługiwać kierunek układu RTL.
Klasa Pomocnicza:
public class LocaleUtils {
private static Locale sLocale;
public static void setLocale(Locale locale) {
sLocale = locale;
if(sLocale != null) {
Locale.setDefault(sLocale);
}
}
public static void updateConfig(ContextThemeWrapper wrapper) {
if(sLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Configuration configuration = new Configuration();
configuration.setLocale(sLocale);
wrapper.applyOverrideConfiguration(configuration);
}
}
public static void updateConfig(Application app, Configuration configuration) {
if (sLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
//Wrapping the configuration to avoid Activity endless loop
Configuration config = new Configuration(configuration);
// We must use the now-deprecated config.locale and res.updateConfiguration here,
// because the replacements aren't available till API level 24 and 17 respectively.
config.locale = sLocale;
Resources res = app.getBaseContext().getResources();
res.updateConfiguration(config, res.getDisplayMetrics());
}
}
}
Zastosowanie:
public class App extends Application {
public void onCreate(){
super.onCreate();
LocaleUtils.setLocale(new Locale("iw"));
LocaleUtils.updateConfig(this, getBaseContext().getResources().getConfiguration());
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocaleUtils.updateConfig(this, newConfig);
}
}
Baza:
public class BaseActivity extends Activity {
public BaseActivity() {
LocaleUtils.updateConfig(this);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-19 15:01:01
To za mój komentarz do odpowiedzi Andreya, ale nie mogę umieścić kodu w komentarzach.
Czy aktywność preferencji jest wywoływana od twojej głównej aktywności? możesz to umieścić w CV...
@Override
protected void onResume() {
if (!(PreferenceManager.getDefaultSharedPreferences(
getApplicationContext()).getString("listLanguage", "en")
.equals(langPreference))) {
refresh();
}
super.onResume();
}
private void refresh() {
finish();
Intent myIntent = new Intent(Main.this, Main.class);
startActivity(myIntent);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-03 01:03:42
Nie mogłem użyć android: anyDensity= "true", ponieważ obiekty w mojej grze byłyby ustawione zupełnie inaczej... wygląda na to, że to też działa:
// creating locale Locale locale2 = new Locale(loc); Locale.setDefault(locale2); Configuration config2 = new Configuration(); config2.locale = locale2; // updating locale mContext.getResources().updateConfiguration(config2, null);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-27 21:11:09
Jeśli chcesz natychmiast zmienić ustawienia regionalne w menu.Musisz to zrobić.
//onCreate method calls only once when menu is called first time.
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
//1.Here you can add your locale settings .
//2.Your menu declaration.
}
//This method is called when your menu is opend to again....
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
menu.clear();
onCreateOptionsMenu(menu);
return super.onMenuOpened(featureId, menu);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-29 14:09:43