Meus usuários podem alterar a localidade no aplicativo (eles podem manter as configurações do telefone em inglês, mas ler o conteúdo do aplicativo em francês, holandês ou qualquer outro idioma ...)
Por que isso está funcionando perfeitamente no 1.5 / 1.6, mas NÃO no 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...
O problema é que o MENU "encolhe" cada vez mais sempre que o usuário passa pelas linhas de código acima ...
Este é o menu que é reduzido:
@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);
}
O que devo fazer no nível 5 da API para que isso funcione novamente?
Eis o código completo, se você deseja testar isso:
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);
}
}
E AQUI ESTÁ O MANIFESTO:
<?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>
Foi o que eu achei:
<uses-sdk android:minSdkVersion="5" />
=> Funciona muito bem ...
<uses-sdk android:minSdkVersion="3" />
=> Menu diminui toda vez que você altera a localidade !!!
como desejo manter meu aplicativo acessível para usuários na versão 1.5, o que devo fazer?
Respostas:
Por meio da pergunta original, não é exatamente sobre o código do idioma todas as outras questões relacionadas ao código do idioma se referem a este. É por isso que eu queria esclarecer a questão aqui. Usei essa pergunta como ponto de partida para meu próprio código de mudança de localidade e descobri que o método não está exatamente correto. Funciona, mas apenas até qualquer alteração na configuração (por exemplo, rotação da tela) e somente nessa Atividade em particular. Jogando com um código por um tempo, acabei com a seguinte abordagem:
Estendi android.app.Application e adicionei o seguinte código:
Esse código garante que todas as atividades tenham um conjunto de códigos de idioma personalizado e não serão redefinidas na rotação e em outros eventos.
Também passei muito tempo tentando fazer com que a alteração de preferência fosse aplicada imediatamente, mas não obteve êxito: o idioma foi alterado corretamente na Reinicialização de atividade, mas os formatos de número e outras propriedades de localidade não foram aplicados até a reinicialização completa do aplicativo.
Muda para
AndroidManifest.xml
Não se esqueça de adicionar
android:configChanges="layoutDirection|locale"
a todas as atividades no AndroidManifest, bem comoandroid:name=".MyApplication"
ao<application>
elemento.fonte
config
enewConfig
). Você deve fazer uma cópiaconfig = new Configuration(config);
primeiro. Passei apenas uma hora depurando esse código antes de descobrir o problema (estava fazendo com que a atividade piscasse sem parar).updateConfiguration()
funciona. Às vezes, sua atividade é exibida em dois idiomas diferentes (especialmente nos Diálogos). Mais informações: stackoverflow.com/questions/39705739/…Depois de uma boa noite de sono, encontrei a resposta na Web (uma simples pesquisa no Google na seguinte linha "
getBaseContext().getResources().updateConfiguration(mConfig, getBaseContext().getResources().getDisplayMetrics());
"), aqui está:link text => este link também mostra o
screenshots
que está acontecendo!Densidade foi o problema aqui , eu precisava ter isso no AndroidManifest.xml
O mais importante é o andróide: anyDensity = "true" .
Não se esqueça de adicionar o seguinte em
AndroidManifest.xml
todas as atividades (para Android 4.1 e abaixo):Esta versão é necessária quando você cria a explicação para o Android 4.2 (API nível 17) aqui :
fonte
activity.recreate()
No Android M, a melhor solução não funciona. Eu escrevi uma classe auxiliar para corrigir o que você deve chamar da classe Application e de todas as atividades (sugiro criar uma BaseActivity e depois fazer com que todas as atividades sejam herdadas.
Nota : Isso também suporta corretamente a direção do layout RTL.
Classe auxiliar:
Inscrição:
BaseActivity:
fonte
BaseActivity()
construtor não deveria ligarsuper()
?<application android:name=".App">
do manifesto? Que tal adicionarandroid:configChanges="layoutDirection|locale"
a todas as atividades no manifesto?Isto é para o meu comentário sobre a resposta de Andrey, mas não posso incluir código nos comentários.
Sua atividade preferencial está sendo chamada de sua atividade principal? você pode colocar isso no resumo ...
fonte
activity.recreate()
recreate()
método, então userecreate()
no lugar derefresh()
no seu código. Isto irá salvar sua linha 3 do código norefresh()
métodoEu não poderia usar o android: anyDensity = "true" porque os objetos no meu jogo seriam posicionados completamente diferentes ... parece que isso também funciona:
fonte
code Locale.setDefault(mLocale); Configuration config = getBaseContext().getResources().getConfiguration(); if (!config.locale.equals(mLocale)) { config.locale = mLocale; getBaseContext().getResources().updateConfiguration(config, null); }
Se você deseja efetuar as opções de menu para alterar a localidade imediatamente, faça o seguinte.
fonte
onMenuOpened
deve ser chamado apenas uma vez, após a alteração da localidade.