Pengguna saya dapat mengubah Lokal dalam aplikasi (mereka mungkin ingin menjaga pengaturan ponsel mereka dalam bahasa Inggris tetapi membaca konten aplikasi saya dalam bahasa Prancis, Belanda atau bahasa lainnya ...)
Mengapa ini berfungsi dengan baik di 1.5 / 1.6 tapi TIDAK di 2.0 lagi ???
@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...
Masalahnya adalah MENU "menyusut" semakin banyak setiap kali pengguna melewati baris kode di atas ...
Ini adalah Menu yang menyusut:
@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);
}
Apa yang harus saya lakukan di API Level 5 untuk membuat ini berfungsi lagi?
DI SINI KODE LENGKAP JIKA ANDA INGIN MENGUJI INI:
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);
}
}
DAN DI SINI ADALAH 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>
INI ADALAH APA YANG SAYA TEMUKAN:
<uses-sdk android:minSdkVersion="5" />
=> ITU BEKERJA HANYA HALUS ...
<uses-sdk android:minSdkVersion="3" />
=> Menu menyusut setiap kali Anda mengubah lokal !!!
karena saya ingin agar aplikasi saya dapat diakses oleh pengguna di 1.5, apa yang harus saya lakukan ??
Jawaban:
Melalui pertanyaan asli tidak persis tentang lokal itu sendiri semua pertanyaan terkait lokal lainnya mengacu pada yang satu ini. Itu sebabnya saya ingin menjelaskan masalah ini di sini. Saya menggunakan pertanyaan ini sebagai titik awal untuk kode switching lokal saya sendiri dan menemukan bahwa metode ini tidak sepenuhnya benar. Ini berfungsi, tetapi hanya sampai konfigurasi berubah (mis. Rotasi layar) dan hanya di aktivitas tertentu. Bermain dengan kode untuk sementara waktu saya berakhir dengan pendekatan berikut:
Saya telah memperpanjang android.app.Application dan menambahkan kode berikut:
Kode ini memastikan bahwa setiap Kegiatan akan memiliki set lokal kustom dan tidak akan diatur ulang pada rotasi dan acara lainnya.
Saya juga menghabiskan banyak waktu untuk mencoba membuat perubahan preferensi diterapkan segera tetapi tidak berhasil: bahasa berubah dengan benar saat Restart aktivitas, tetapi format angka dan properti lokal lainnya tidak diterapkan sampai aplikasi penuh restart.
Perubahan menjadi
AndroidManifest.xml
Jangan lupa menambahkan
android:configChanges="layoutDirection|locale"
ke setiap aktivitas di AndroidManifest, dan jugaandroid:name=".MyApplication"
ke<application>
elemen.sumber
config
dannewConfig
). Anda harus membuat salinannyaconfig = new Configuration(config);
terlebih dahulu. Saya baru saja menghabiskan satu jam men-debug kode ini sebelum menemukan masalah (itu menyebabkan aktivitas flash tanpa henti).updateConfiguration()
kerjanya, jadi terkadang Aktivitas Anda akan ditampilkan dalam 2 bahasa yang berbeda (terutama dalam Dialog). Info lebih lanjut: stackoverflow.com/questions/39705739/…Setelah tidur nyenyak, saya menemukan jawabannya di Web (pencarian Google sederhana pada baris berikut "
getBaseContext().getResources().updateConfiguration(mConfig, getBaseContext().getResources().getDisplayMetrics());
"), ini dia:tautan teks => tautan ini juga menunjukkan
screenshots
apa yang terjadi!Kepadatan adalah masalah di sini , saya perlu memiliki ini di AndroidManifest.xml
Yang paling penting adalah android: anyDensity = "true" .
Jangan lupa untuk menambahkan yang berikut ini di
AndroidManifest.xml
untuk setiap aktivitas (untuk Android 4.1 dan di bawah):Versi ini diperlukan saat Anda membuat penjelasan untuk Android 4.2 (API level 17) di sini :
sumber
activity.recreate()
Di Android M solusi teratas tidak akan berfungsi. Saya telah menulis sebuah kelas pembantu untuk memperbaiki apa yang harus Anda panggil dari kelas Aplikasi Anda dan semua Kegiatan (Saya akan menyarankan membuat BaseActivity dan kemudian membuat semua Kegiatan mewarisi darinya.
Catatan : Ini juga akan mendukung arah tata letak RTL dengan benar.
Kelas pembantu:
Aplikasi:
BaseActivity:
sumber
BaseActivity()
konstruktor memanggilsuper()
?<application android:name=".App">
manifes? Bagaimana kalau menambahkanandroid:configChanges="layoutDirection|locale"
ke setiap aktivitas di manifes?Ini untuk komentar saya pada jawaban Andrey tapi saya tidak bisa memasukkan kode dalam komentar.
Apakah Anda memilih aktivitas yang dipanggil dari aktivitas utama Anda? Anda dapat menempatkan ini di resume ...
sumber
activity.recreate()
recreate()
metode, jadi gunakanrecreate()
direfresh()
dalam kode Anda. Ini akan menghemat 3 baris kode Anda dalamrefresh()
metodeSaya tidak bisa menggunakan android: anyDensity = "true" karena objek dalam gim saya akan diposisikan sangat berbeda ... sepertinya ini juga cukup membantu:
sumber
code Locale.setDefault(mLocale); Configuration config = getBaseContext().getResources().getConfiguration(); if (!config.locale.equals(mLocale)) { config.locale = mLocale; getBaseContext().getResources().updateConfiguration(config, null); }
Jika Anda ingin memberi efek pada opsi menu untuk segera mengubah lokal. Anda harus melakukan ini.
sumber
onMenuOpened
harus dipanggil hanya sekali, setelah perubahan lokal.