Mis usuarios pueden cambiar la configuración regional dentro de la aplicación (pueden querer mantener la configuración de su teléfono en inglés pero leer el contenido de mi aplicación en francés, holandés o en cualquier otro idioma ...)
¿Por qué esto funciona perfectamente bien en 1.5 / 1.6 pero ya no en 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...
El problema es que el MENÚ se "encoge" cada vez más cada vez que el usuario pasa por las líneas de código anteriores ...
Este es el menú que se reduce:
@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);
}
¿Qué debo hacer en API Nivel 5 para que esto funcione nuevamente?
AQUÍ ESTÁ EL CÓDIGO COMPLETO SI DESEA PROBAR ESTO:
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);
}
}
Y aquí está el manifiesto:
<?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>
ESTO ES LO QUE ENCONTRÉ:
<uses-sdk android:minSdkVersion="5" />
=> FUNCIONA SOLO BIEN ...
<uses-sdk android:minSdkVersion="3" />
=> ¡El menú se reduce cada vez que cambia la configuración regional!
Como quiero mantener mi aplicación accesible para los usuarios en 1.5, ¿qué debo hacer?
Respuestas:
A través de la pregunta original no se trata exactamente de la configuración regional en sí, todas las demás preguntas relacionadas con la configuración regional hacen referencia a esta. Es por eso que quería aclarar el problema aquí. Utilicé esta pregunta como punto de partida para mi propio código de cambio de configuración regional y descubrí que el método no es exactamente correcto. Funciona, pero solo hasta que cambie la configuración (por ejemplo, rotación de pantalla) y solo en esa Actividad en particular. Jugando con un código por un tiempo, terminé con el siguiente enfoque:
He extendido android.app.Application y agregué el siguiente código:
Este código garantiza que cada actividad tendrá un entorno local personalizado y no se restablecerá en la rotación y otros eventos.
También pasé mucho tiempo tratando de hacer que el cambio de preferencia se aplicara de inmediato, pero no tuve éxito: el idioma cambió correctamente al reiniciar la actividad, pero los formatos de números y otras propiedades locales no se aplicaron hasta el reinicio completo de la aplicación.
Cambios a
AndroidManifest.xml
No olvide agregar
android:configChanges="layoutDirection|locale"
a cada actividad en AndroidManifest, así como tambiénandroid:name=".MyApplication"
al<application>
elemento.fuente
config
ynewConfig
). Debe hacer una copia conconfig = new Configuration(config);
primero. Acabo de pasar una hora depurando este código antes de descubrir el problema (estaba causando que la actividad parpadeara interminablemente).updateConfiguration()
funciona, por lo que a veces su Actividad se mostrará en 2 idiomas diferentes (especialmente en Diálogos). Más información: stackoverflow.com/questions/39705739/…Después de una buena noche de sueño, encontré la respuesta en la Web (una simple búsqueda en Google en la siguiente línea "
getBaseContext().getResources().updateConfiguration(mConfig, getBaseContext().getResources().getDisplayMetrics());
"), aquí está:texto del enlace => ¡este enlace también muestra
screenshots
lo que está sucediendo!La densidad era el problema aquí , necesitaba tener esto en AndroidManifest.xml
El más importante es el Android: anyDensity = "true" .
No olvide agregar lo siguiente en
AndroidManifest.xml
cada actividad (para Android 4.1 y siguientes):Esta versión es necesaria cuando compila para Android 4.2 (API nivel 17) explicación aquí :
fuente
activity.recreate()
En Android M, la mejor solución no funcionará. He escrito una clase auxiliar para arreglar lo que debe llamar desde su clase de Aplicación y todas las Actividades (sugeriría crear una BaseActivity y luego hacer que todas las Actividades hereden de ella.
Nota : Esto también admitirá correctamente la dirección de diseño RTL.
Clase auxiliar:
Solicitud:
Actividad base:
fuente
BaseActivity()
llamar el constructorsuper()
?<application android:name=".App">
en el manifiesto? ¿Qué tal agregarandroid:configChanges="layoutDirection|locale"
a cada actividad en el manifiesto?Esto es para mi comentario sobre la respuesta de Andrey, pero no puedo incluir el código en los comentarios.
¿Se llama su actividad de preferencia desde su actividad principal? podrías colocar esto en el currículum vitae ...
fuente
activity.recreate()
recreate()
método, así que úselorecreate()
en lugar derefresh()
su código. Esto ahorrará su línea de código 3 en elrefresh()
métodoNo pude usar android: anyDensity = "true" porque los objetos en mi juego se posicionarían completamente diferentes ... parece que esto también funciona:
fuente
code Locale.setDefault(mLocale); Configuration config = getBaseContext().getResources().getConfiguration(); if (!config.locale.equals(mLocale)) { config.locale = mLocale; getBaseContext().getResources().updateConfiguration(config, null); }
Si desea realizar un efecto en las opciones del menú para cambiar la configuración regional de inmediato, debe hacer esto.
fuente
onMenuOpened
debería llamarse solo una vez, después del cambio de configuración regional.