Waktu untuk pembaruan yang seharusnya.
Pertama, daftar yang sudah tidak digunakan lagi dengan API yang sudah tidak digunakan lagi:
configuration.locale
(API 17)
updateConfiguration(configuration, displaymetrics)
(API 17)
Hal yang tidak dijawab oleh pertanyaan baru-baru ini adalah penggunaan metode baru .
createConfigurationContext adalah metode baru untuk memperbaruiConfiguration.
Beberapa telah menggunakannya sendiri seperti ini:
Configuration overrideConfiguration = ctx.getResources().getConfiguration();
Locale locale = new Locale("en_US");
overrideConfiguration.setLocale(locale);
createConfigurationContext(overrideConfiguration);
... tapi itu tidak berhasil. Mengapa? Metode mengembalikan konteks, yang kemudian digunakan untuk menangani terjemahan Strings.xml dan sumber daya lokal lainnya (gambar, tata letak, apa pun).
Penggunaan yang tepat seperti ini:
Configuration overrideConfiguration = ctx.getResources().getConfiguration();
Locale locale = new Locale("en_US");
overrideConfiguration.setLocale(locale);
//the configuration can be used for other stuff as well
Context context = createConfigurationContext(overrideConfiguration);
Resources resources = context.getResources();
Jika Anda hanya menyalin-menempelkannya ke IDE Anda, Anda mungkin melihat peringatan bahwa API mengharuskan Anda menargetkan API 17 atau lebih tinggi. Ini bisa diselesaikan dengan memasukkannya ke dalam metode dan menambahkan anotasi@TargetApi(17)
Tapi tunggu. Bagaimana dengan API yang lebih lama?
Anda perlu membuat metode lain menggunakan updateConfiguration tanpa anotasi TargetApi.
Resources res = YourApplication.getInstance().getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale("th");
res.updateConfiguration(conf, dm);
Anda tidak perlu mengembalikan konteks di sini.
Sekarang, mengelola ini bisa sulit. Di API 17+ Anda memerlukan konteks yang dibuat (atau sumber daya dari konteks yang dibuat) untuk mendapatkan sumber daya yang sesuai berdasarkan lokalisasi. bagaimana kamu menangani ini?
Nah, inilah cara saya melakukannya:
/**
* Full locale list: /programming/7973023/what-is-the-list-of-supported-languages-locales-on-android
* @param lang language code (e.g. en_US)
* @return the context
* PLEASE READ: This method can be changed for usage outside an Activity. Simply add a COntext to the arguments
*/
public Context setLanguage(String lang/*, Context c*/){
Context c = AndroidLauncher.this;//remove if the context argument is passed. This is a utility line, can be removed totally by replacing calls to c with the activity (if argument Context isn't passed)
int API = Build.VERSION.SDK_INT;
if(API >= 17){
return setLanguage17(lang, c);
}else{
return setLanguageLegacy(lang, c);
}
}
/**
* Set language for API 17
* @param lang
* @param c
* @return
*/
@TargetApi(17)
public Context setLanguage17(String lang, Context c){
Configuration overrideConfiguration = c.getResources().getConfiguration();
Locale locale = new Locale(lang);
Locale.setDefault(locale);
overrideConfiguration.setLocale(locale);
//the configuration can be used for other stuff as well
Context context = createConfigurationContext(overrideConfiguration);//"local variable is redundant" if the below line is uncommented, it is needed
//Resources resources = context.getResources();//If you want to pass the resources instead of a Context, uncomment this line and put it somewhere useful
return context;
}
public Context setLanguageLegacy(String lang, Context c){
Resources res = c.getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();//Utility line
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale(lang);//setLocale requires API 17+ - just like createConfigurationContext
Locale.setDefault(conf.locale);
res.updateConfiguration(conf, dm);
//Using this method you don't need to modify the Context itself. Setting it at the start of the app is enough. As you
//target both API's though, you want to return the context as you have no clue what is called. Now you can use the Context
//supplied for both things
return c;
}
Kode ini berfungsi dengan memiliki satu metode yang membuat panggilan ke metode yang sesuai berdasarkan API apa. Ini adalah sesuatu yang telah saya lakukan dengan banyak panggilan usang yang berbeda (termasuk Html.fromHtml). Anda memiliki satu metode yang memperhitungkan argumen yang diperlukan, yang kemudian membaginya menjadi salah satu dari dua (atau tiga atau lebih) metode dan mengembalikan hasil yang sesuai berdasarkan tingkat API. Ini fleksibel karena Anda tidak perlu memeriksa beberapa kali, metode "entri" melakukannya untuk Anda. Metode entri di sini adalahsetLanguage
HARAP BACA INI SEBELUM MENGGUNAKANNYA
Anda perlu menggunakan Konteks yang dikembalikan saat Anda mendapatkan sumber daya. Mengapa? Saya telah melihat jawaban lain di sini yang menggunakan createConfigurationContext dan tidak menggunakan konteks yang dikembalikan. Untuk membuatnya berfungsi seperti itu, updateConfiguration harus dipanggil. Yang sudah usang. Gunakan konteks yang dikembalikan oleh metode untuk mendapatkan sumber daya.
Contoh penggunaan :
Konstruktor atau sejenisnya:
ctx = getLanguage(lang);//lang is loaded or generated. How you get the String lang is not something this answer handles (nor will handle in the future)
Dan kemudian, di mana pun Anda ingin mendapatkan sumber daya yang Anda lakukan:
String fromResources = ctx.getString(R.string.helloworld);
Menggunakan konteks lain akan (secara teori) mematahkan ini.
AFAIK Anda masih harus menggunakan konteks aktivitas untuk menampilkan dialog atau bersulang. untuk itu Anda dapat menggunakan contoh aktivitas (jika Anda berada di luar)
Dan akhirnya, gunakan recreate()
pada aktivitas untuk menyegarkan konten. Jalan pintas untuk tidak harus membuat maksud untuk menyegarkan.