Thời gian cho một bản cập nhật do.
Trước hết, danh sách không dùng nữa với API mà nó không được dùng nữa:
configuration.locale
(API 17)
updateConfiguration(configuration, displaymetrics)
(API 17)
Điều không có câu hỏi nào được trả lời gần đây đã đúng là việc sử dụng phương pháp mới .
createdConfigurationContext là phương thức mới để updateConfiguration.
Một số đã sử dụng nó độc lập như thế này:
Configuration overrideConfiguration = ctx.getResources().getConfiguration();
Locale locale = new Locale("en_US");
overrideConfiguration.setLocale(locale);
createConfigurationContext(overrideConfiguration);
... nhưng điều đó không hiệu quả. Tại sao? Phương thức này trả về một bối cảnh, sau đó được sử dụng để xử lý các bản dịch String.xml và các tài nguyên được bản địa hóa khác (hình ảnh, bố cục, bất cứ thứ gì).
Cách sử dụng thích hợp là như thế này:
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();
Nếu bạn vừa sao chép nó vào IDE của mình, bạn có thể thấy cảnh báo rằng API yêu cầu bạn nhắm mục tiêu API 17 trở lên. Điều này có thể được giải quyết bằng cách đặt nó vào một phương thức và thêm chú thích@TargetApi(17)
Nhưng chờ đã. Còn các API cũ hơn thì sao?
Bạn cần tạo một phương thức khác bằng cách sử dụng updateConfiguration mà không cần chú thích 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);
Bạn không cần phải trả lại một bối cảnh ở đây.
Bây giờ, quản lý những điều này có thể khó khăn. Trong API 17+, bạn cần bối cảnh được tạo (hoặc tài nguyên từ ngữ cảnh được tạo) để có được tài nguyên phù hợp dựa trên nội địa hóa. Làm thế nào bạn có thể xoay xở được chuyện này?
Vâng, đây là cách tôi làm:
/**
* 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;
}
Mã này hoạt động bằng cách có một phương thức thực hiện các cuộc gọi đến phương thức thích hợp dựa trên API nào. Đây là điều tôi đã thực hiện với rất nhiều cuộc gọi không dùng nữa (bao gồm Html.fromHtml). Bạn có một phương thức nhận các đối số cần thiết, sau đó chia nó thành một trong hai (hoặc ba hoặc nhiều hơn) phương thức và trả về kết quả phù hợp dựa trên mức API. Nó linh hoạt vì bạn không phải kiểm tra nhiều lần, phương pháp "entry" thực hiện cho bạn. Phương thức nhập ở đây làsetLanguage
VUI LÒNG ĐỌC NÀY TRƯỚC KHI SỬ DỤNG NÓ
Bạn cần sử dụng Bối cảnh được trả về khi bạn nhận được tài nguyên. Tại sao? Tôi đã thấy các câu trả lời khác ở đây, những người sử dụng createdConfigurationContext và không sử dụng bối cảnh mà nó trả về. Để làm cho nó hoạt động như vậy, updateConfiguration phải được gọi. Mà bị phản đối. Sử dụng bối cảnh được trả về bởi phương thức để lấy tài nguyên.
Ví dụ sử dụng :
Nhà xây dựng hoặc nơi nào đó tương tự:
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)
Và sau đó, bất cứ nơi nào bạn muốn nhận tài nguyên bạn làm:
String fromResources = ctx.getString(R.string.helloworld);
Sử dụng bất kỳ bối cảnh nào khác sẽ (về lý thuyết) phá vỡ điều này.
AFAIK bạn vẫn phải sử dụng bối cảnh hoạt động để hiển thị các hộp thoại hoặc Toasts. cho rằng bạn có thể sử dụng một thể hiện của một hoạt động (nếu bạn ở bên ngoài)
Và cuối cùng, sử dụng recreate()
trên các hoạt động để làm mới nội dung. Phím tắt để không phải tạo ra một ý định để làm mới.