Мои пользователи могут изменить языковой стандарт в приложении (они могут захотеть сохранить настройки своего телефона на английском, но читать содержимое моего приложения на французском, голландском или любом другом языке ...)
Почему это работает прекрасно в 1.5 / 1.6, а НЕ в 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...
Проблема в том, что МЕНЮ «сжимается» все больше и больше каждый раз, когда пользователь проходит строки кода выше ...
Это меню, которое сокращается:
@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);
}
Что я должен сделать в API Level 5, чтобы эта работа снова?
Вот полный код, если вы хотите проверить это:
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);
}
}
И вот это манифест:
<?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>
Это то, что я нашел:
<uses-sdk android:minSdkVersion="5" />
=> Это работает просто отлично
<uses-sdk android:minSdkVersion="3" />
=> Меню сжимается каждый раз, когда вы меняете локаль !!!
как я хочу, чтобы мое приложение было доступно для пользователей версии 1.5, что мне делать ??
Ответы:
Исходный вопрос не совсем о самой локали, все остальные вопросы, связанные с локалью, относятся к этому. Вот почему я хотел уточнить эту проблему здесь. Я использовал этот вопрос в качестве отправной точки для своего собственного кода переключения локали и обнаружил, что метод не совсем правильный. Это работает, но только до какого-либо изменения конфигурации (например, поворот экрана) и только в этой конкретной деятельности. Некоторое время играя с кодом, я получил следующий подход:
Я расширил приложение android.app.Application и добавил следующий код:
Этот код гарантирует, что для каждого действия будет установлен пользовательский языковой стандарт, и он не будет сброшен при повороте и других событиях.
Я также потратил много времени, пытаясь сделать изменение предпочтений незамедлительным, но безуспешно: язык изменился правильно при перезапуске Activity, но числовые форматы и другие свойства локали не применялись до полного перезапуска приложения.
Изменения к
AndroidManifest.xml
Не забудьте добавить
android:configChanges="layoutDirection|locale"
к каждому действию на AndroidManifest, а такжеandroid:name=".MyApplication"
к<application>
элементу.источник
config
иnewConfig
). Вы должны сделать копию сconfig = new Configuration(config);
первым. Я просто потратил час на отладку этого кода, прежде чем обнаружил проблему (это вызывало бесконечную вспышку активности).updateConfiguration()
работы, поэтому иногда ваша активность будет отображаться на 2 разных языках (особенно в диалогах). Дополнительная информация: stackoverflow.com/questions/39705739/…После хорошего сна я нашел ответ в Интернете (простой поиск Google в следующей строке "
getBaseContext().getResources().updateConfiguration(mConfig, getBaseContext().getResources().getDisplayMetrics());
"), вот он:текст ссылки => эта ссылка также показывает,
screenshots
что происходит!Плотность была проблема здесь , мне нужно было это в AndroidManifest.xml
Наиболее важным является android: anyDensity = "true" .
Не забудьте добавить следующее
AndroidManifest.xml
для каждого действия (для Android 4.1 и ниже):Эта версия необходима при сборке объяснения для Android 4.2 (уровень API 17) здесь :
источник
activity.recreate()
В Android M лучшее решение не будет работать. Я написал вспомогательный класс для исправления того, что вы должны вызывать из класса приложения и всех операций (я бы предложил создать BaseActivity, а затем сделать все действия наследуемыми от него.
Примечание : Это также будет правильно поддерживать направление расположения RTL.
Хелпер класс:
Заявка:
BaseActivity:
источник
BaseActivity()
конструктор не должен вызыватьsuper()
?<application android:name=".App">
манифеста? Как насчет добавленияandroid:configChanges="layoutDirection|locale"
к каждому действию в манифесте?Это мой комментарий к ответу Андрея, но я не могу включить код в комментарии.
Ваша предпочтительная деятельность вызывается из вашей основной деятельности? Вы могли бы поместить это в резюме ...
источник
activity.recreate()
recreate()
метод, поэтому используйте егоrecreate()
вместоrefresh()
в вашем коде. Это сохранит ваши 3 строки кода вrefresh()
методеЯ не мог использовать android: anyDensity = "true", потому что объекты в моей игре были бы расположены совершенно по-другому ... кажется, это тоже помогает:
источник
code Locale.setDefault(mLocale); Configuration config = getBaseContext().getResources().getConfiguration(); if (!config.locale.equals(mLocale)) { config.locale = mLocale; getBaseContext().getResources().updateConfiguration(config, null); }
Если вы хотите повлиять на параметры меню для немедленного изменения локали. Вам нужно сделать это следующим образом.
источник
onMenuOpened
должен быть вызван только один раз, после изменения локали.