Có thể thay đổi ngôn ngữ của một ứng dụng theo chương trình trong khi vẫn sử dụng tài nguyên Android không?
Nếu không, có thể yêu cầu tài nguyên bằng một ngôn ngữ cụ thể không?
Tôi muốn cho phép người dùng thay đổi ngôn ngữ của ứng dụng từ ứng dụng.
Có thể thay đổi ngôn ngữ của một ứng dụng theo chương trình trong khi vẫn sử dụng tài nguyên Android không?
Nếu không, có thể yêu cầu tài nguyên bằng một ngôn ngữ cụ thể không?
Tôi muốn cho phép người dùng thay đổi ngôn ngữ của ứng dụng từ ứng dụng.
Câu trả lời:
Điều đó là có thể. Bạn có thể đặt miền địa phương. Tuy nhiên, tôi không khuyến khích điều đó. Chúng tôi đã thử nó ở giai đoạn đầu, về cơ bản nó đang chiến đấu với hệ thống.
Chúng tôi có cùng yêu cầu thay đổi ngôn ngữ nhưng quyết định giải quyết thực tế là UI phải giống với UI điện thoại. Nó đã hoạt động thông qua cài đặt ngôn ngữ nhưng quá lỗi. Và bạn phải đặt nó mỗi khi bạn vào hoạt động (từng hoạt động) từ kinh nghiệm của tôi. Đây là một mã nếu bạn vẫn cần cái này (một lần nữa, tôi không khuyến nghị điều đó)
Resources res = context.getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.setLocale(new Locale(language_code.toLowerCase())); // API 17+ only.
// Use conf.locale = new Locale(...) if targeting lower versions
res.updateConfiguration(conf, dm);
Nếu bạn có nội dung cụ thể về ngôn ngữ - bạn có thể thay đổi cơ sở đó trên cài đặt.
cập nhật vào ngày 26 tháng 3 năm 2020
public static void setLocale(Activitycontext) {
Locale locale;
Sessions session = new Sessions(context);
//Log.e("Lan",session.getLanguage());
locale = new Locale(langCode);
Configuration config = new Configuration(context.getResources().getConfiguration());
Locale.setDefault(locale);
config.setLocale(locale);
context.getBaseContext().getResources().updateConfiguration(config,
context.getBaseContext().getResources().getDisplayMetrics());
}
Context.createConfigurationContext(), có thể được sử dụng để bọc bối cảnh mặc định với cấu hình dành riêng cho miền địa phương và sau đó gọi getResourcesnó mà không phải cập nhật cấu hình trên các đối tượng tài nguyên.
conf.setLayoutDirection(locale), bạn có thể thay thế conf.locale = new Locale(...))bằng conf.setLocale(new Locale(...)). Nó sẽ gọi nội bộ setLayoutDirection.
Mã này thực sự hoạt động:
fa = tiếng Ba Tư, en = tiếng anh
Nhập mã ngôn ngữ của bạn trong languageToLoadbiến:
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
public class Main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String languageToLoad = "fa"; // your language
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
this.setContentView(R.layout.main);
}
}
Resources.updateConfigurationphương thức. Tôi đã thụt mã để làm cho nó rõ ràng hơn.
Tôi đang tìm cách thay đổi ngôn ngữ hệ thống theo chương trình. Mặc dù tôi hoàn toàn hiểu rằng một ứng dụng bình thường không bao giờ nên làm điều đó và thay vào đó:
cần phải thực sự thay đổi ngôn ngữ của hệ thống theo chương trình.
Đây là API không có giấy tờ và do đó không nên được sử dụng cho các ứng dụng thị trường / người dùng cuối!
Dù sao đây là giải pháp tôi tìm thấy:
Locale locale = new Locale(targetLocaleAsString);
Class amnClass = Class.forName("android.app.ActivityManagerNative");
Object amn = null;
Configuration config = null;
// amn = ActivityManagerNative.getDefault();
Method methodGetDefault = amnClass.getMethod("getDefault");
methodGetDefault.setAccessible(true);
amn = methodGetDefault.invoke(amnClass);
// config = amn.getConfiguration();
Method methodGetConfiguration = amnClass.getMethod("getConfiguration");
methodGetConfiguration.setAccessible(true);
config = (Configuration) methodGetConfiguration.invoke(amn);
// config.userSetLocale = true;
Class configClass = config.getClass();
Field f = configClass.getField("userSetLocale");
f.setBoolean(config, true);
// set the locale to the new value
config.locale = locale;
// amn.updateConfiguration(config);
Method methodUpdateConfiguration = amnClass.getMethod("updateConfiguration", Configuration.class);
methodUpdateConfiguration.setAccessible(true);
methodUpdateConfiguration.invoke(amn, config);
android.permission.CHANGE_CONFIGURATIONchỉ có thể được cấp bởi ứng dụng được ký với khóa thực hiện.
Nếu bạn muốn bảo đảm ngôn ngữ đã thay đổi trên tất cả ứng dụng của bạn, bạn phải thực hiện hai điều.
Đầu tiên, tạo một Hoạt động cơ bản và làm cho tất cả các hoạt động của bạn mở rộng từ đây:
public class BaseActivity extends AppCompatActivity {
private Locale mCurrentLocale;
@Override
protected void onStart() {
super.onStart();
mCurrentLocale = getResources().getConfiguration().locale;
}
@Override
protected void onRestart() {
super.onRestart();
Locale locale = getLocale(this);
if (!locale.equals(mCurrentLocale)) {
mCurrentLocale = locale;
recreate();
}
}
public static Locale getLocale(Context context){
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
String lang = sharedPreferences.getString("language", "en");
switch (lang) {
case "English":
lang = "en";
break;
case "Spanish":
lang = "es";
break;
}
return new Locale(lang);
}
}
Lưu ý rằng tôi lưu ngôn ngữ mới trong sharedPreference.
Thứ hai, tạo một phần mở rộng của Ứng dụng như thế này:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
setLocale();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setLocale();
}
private void setLocale() {
final Resources resources = getResources();
final Configuration configuration = resources.getConfiguration();
final Locale locale = getLocale(this);
if (!configuration.locale.equals(locale)) {
configuration.setLocale(locale);
resources.updateConfiguration(configuration, null);
}
}
}
Lưu ý rằng getLocale () giống như trên.
Đó là tất cả! Tôi hy vọng điều này có thể giúp ai đó.
Applicationnó là gì và cách sử dụng. mobomo.com/2011/05/how-to-use-application-object-of-android
configuration.locatekhông được dùng nữa, setLocale yêu cầu API 17+ và updateConfiguration bị phản đối
Theo bài báo này . Bạn sẽ cần phải tải về LocaleHelper.javatham chiếu trong bài viết đó.
MyApplicationlớp sẽ mở rộngApplication attachBaseContext()để cập nhật ngôn ngữ.Đăng ký lớp học này trong bảng kê khai.
public class MyApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
}
}
<application
android:name="com.package.MyApplication"
.../>Tạo BaseActivityvà ghi đè onAttach()để cập nhật ngôn ngữ. Cần thiết cho Android 6+
public class BaseActivity extends Activity {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
}Làm cho tất cả các hoạt động trên ứng dụng của bạn kéo dài từ BaseActivity.
public class LocaleHelper {
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
String lang = getPersistedData(context, Locale.getDefault().getLanguage());
return setLocale(context, lang);
}
public static Context onAttach(Context context, String defaultLanguage) {
String lang = getPersistedData(context, defaultLanguage);
return setLocale(context, lang);
}
public static String getLanguage(Context context) {
return getPersistedData(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
persist(context, language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
}
return updateResourcesLegacy(context, language);
}
private static String getPersistedData(Context context, String defaultLanguage) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}
private static void persist(Context context, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.apply();
}
@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLayoutDirection(locale);
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}Chỉ cần thêm một mảnh thêm mà làm tôi vấp ngã.
Trong khi các câu trả lời khác hoạt động tốt với "de" chẳng hạn
String lang = "de";
Locale locale = new Locale(lang);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
Các ví dụ trên không hoạt động với "fr_BE"ngôn ngữ ví dụ để nó sẽ sử dụng values-fr-rBEthư mục hoặc tương tự.
Cần thay đổi nhỏ sau đây để làm việc với "fr_BE"
String lang = "fr";
//create a string for country
String country = "BE";
//use constructor with country
Locale locale = new Locale(lang, country);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
activity.recreate()
android.content.res.Configuration conf = res.getConfiguration();thay vì tạo một Configurationthể hiện mới thì sao? Có bất kỳ lợi ích cho việc sử dụng một cái mới?
Tôi đã thay đổi ngôn ngữ tiếng Đức cho ứng dụng của mình bắt đầu.
Đây là mã chính xác của tôi. Bất cứ ai cũng muốn sử dụng điều này cho tôi .. (Cách thay đổi ngôn ngữ trong Android theo chương trình)
mã của tôi:
Configuration config ; // variable declaration in globally
// this part is given inside onCreate Method starting and before setContentView()
public void onCreate(Bundle icic)
{
super.onCreate(icic);
config = new Configuration(getResources().getConfiguration());
config.locale = Locale.GERMAN ;
getResources().updateConfiguration(config,getResources().getDisplayMetrics());
setContentView(R.layout.newdesign);
}
Tôi biết đã muộn để trả lời nhưng tôi tìm thấy bài viết này ở đây . Điều này giải thích toàn bộ quá trình rất tốt và cung cấp cho bạn một mã có cấu trúc tốt.
Lớp người trợ giúp địa phương:
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.preference.PreferenceManager;
import java.util.Locale;
/**
* This class is used to change your application locale and persist this change for the next time
* that your app is going to be used.
* <p/>
* You can also change the locale of your application on the fly by using the setLocale method.
* <p/>
* Created by gunhansancar on 07/10/15.
*/
public class LocaleHelper {
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
String lang = getPersistedData(context, Locale.getDefault().getLanguage());
return setLocale(context, lang);
}
public static Context onAttach(Context context, String defaultLanguage) {
String lang = getPersistedData(context, defaultLanguage);
return setLocale(context, lang);
}
public static String getLanguage(Context context) {
return getPersistedData(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
persist(context, language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
}
return updateResourcesLegacy(context, language);
}
private static String getPersistedData(Context context, String defaultLanguage) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}
private static void persist(Context context, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.apply();
}
@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLayoutDirection(locale);
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}
Bạn cần ghi đè AttachBaseContext và gọi LocaleHelper.onAttach () để khởi tạo cài đặt ngôn ngữ trong ứng dụng của bạn.
import android.app.Application;
import android.content.Context;
import com.gunhansancar.changelanguageexample.helper.LocaleHelper;
public class MainApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
}
}
Tất cả bạn phải làm là thêm
LocaleHelper.onCreate(this, "en");
bất cứ nơi nào bạn muốn thay đổi miền địa phương.
createConfigurationContext, thật hữu ích
Tạo một lớp Mở rộng Applicationvà tạo một phương thức tĩnh. Sau đó, bạn có thể gọi phương thức này trong tất cả các hoạt động trước setContentView().
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
}
public static void setLocaleFa (Context context){
Locale locale = new Locale("fa");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
context.getApplicationContext().getResources().updateConfiguration(config, null);
}
public static void setLocaleEn (Context context){
Locale locale = new Locale("en_US");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
context.getApplicationContext().getResources().updateConfiguration(config, null);
}
}
Sử dụng trong các hoạt động:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApp.setLocaleFa(MainActivity.this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
}
Thay đổi ngôn ngữ theo chương trình trong Android
Câu trả lời cũ
Điều này bao gồm hỗ trợ RTL / LTR:
public static void changeLocale(Context context, Locale locale) {
Configuration conf = context.getResources().getConfiguration();
conf.locale = locale;
Locale.setDefault(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
conf.setLayoutDirection(conf.locale);
}
context.getResources().updateConfiguration(conf, context.getResources().getDisplayMetrics());
}
Giải pháp duy nhất hoàn toàn phù hợp với tôi là kết hợp mã của Alex Volovoy với cơ chế khởi động lại ứng dụng:
void restartApplication() {
Intent i = new Intent(MainTabActivity.context, MagicAppRestart.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainTabActivity.context.startActivity(i);
}
/** This activity shows nothing; instead, it restarts the android process */
public class MagicAppRestart extends Activity {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
finish();
}
protected void onResume() {
super.onResume();
startActivityForResult(new Intent(this, MainTabActivity.class), 0);
}
}
activity.recreate()
Tôi đã phải đối mặt với cùng một vấn đề. Trên GitHub tôi đã tìm thấy thư viện Android-LocalizationActivity .
Thư viện này giúp việc thay đổi ngôn ngữ của ứng dụng của bạn trong thời gian chạy rất đơn giản, như bạn có thể thấy trong mẫu mã bên dưới. Một dự án mẫu bao gồm mã mẫu bên dưới và nhiều thông tin hơn có thể được tìm thấy tại trang github.
LocalizationActivity mở rộng AppCompatActivity, vì vậy bạn cũng có thể sử dụng nó khi bạn đang sử dụng Fragment.
public class MainActivity extends LocalizationActivity implements View.OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple);
findViewById(R.id.btn_th).setOnClickListener(this);
findViewById(R.id.btn_en).setOnClickListener(this);
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btn_en) {
setLanguage("en");
} else if (id == R.id.btn_th) {
setLanguage("th");
}
}
}
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
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.
Nếu bạn viết
android:configChanges="locale"
Trong mọi hoạt động (trong tệp kê khai) thì không cần phải đặt nó mỗi khi bạn nhập Activity.
configChangesđược sử dụng cho một vụ hack để duy trì trạng thái Hoạt động trên các góc quay / v.v.
Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration config = context.getResources().getConfiguration();
config.setLocale(locale);
context.createConfigurationContext(config);
Cập nhật quan trọng:
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
Lưu ý rằng trên SDK> = 21, bạn cần gọi 'Tài nguyên.updateConfiguration ()' , nếu không tài nguyên sẽ không được cập nhật.
Context ctx = createConfigurationContext(args);và lấy tài nguyên từ đó
/*change language at Run-time*/
//use method like that:
//setLocale("en");
public void setLocale(String lang) {
myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
Intent refresh = new Intent(this, AndroidLocalize.class);
startActivity(refresh);
}
activity.recreate()
Locale configurationnên được đặt trong mỗi activitytrước khi thiết lập nội dung -this.setContentView(R.layout.main);
activity.recreate()
Đầu tiên, tạo nhiều chuỗi tệp cho các ngôn ngữ khác nhau; sau đó sử dụng khối mã này trong onCreate()phương thức:
super.onCreate(savedInstanceState);
String languageToLoad = "fr"; // change your language here
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
this.setContentView(R.layout.main);
Đây là một số mã làm việc cho tôi:
public class MainActivity extends AppCompatActivity {
public static String storeLang;
@Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences shp = PreferenceManager.getDefaultSharedPreferences(this);
storeLang = shp.getString(getString(R.string.key_lang), "");
// Create a new Locale object
Locale locale = new Locale(storeLang);
// Create a new configuration object
Configuration config = new Configuration();
// Set the locale of the new configuration
config.locale = locale;
// Update the configuration of the Accplication context
getResources().updateConfiguration(
config,
getResources().getDisplayMetrics()
);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Nguồn: tại đây
Không có giải pháp nào được liệt kê ở đây giúp tôi.
Ngôn ngữ không bật trên android> = 7.0 nếu AppCompatDelegate.setDefaultNightMode (AppCompatDelegate.MODE_NIGHT_YES)
LocaleUtils này hoạt động tốt: https://gist.github.com/GigigoGreenLabs/7d555c762ba2d3a810fe
LocaleUtils
public class LocaleUtils {
public static final String LAN_SPANISH = "es";
public static final String LAN_PORTUGUESE = "pt";
public static final String LAN_ENGLISH = "en";
private static Locale sLocale;
public static void setLocale(Locale locale) {
sLocale = locale;
if(sLocale != null) {
Locale.setDefault(sLocale);
}
}
public static void updateConfig(ContextThemeWrapper wrapper) {
if(sLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Configuration configuration = new Configuration();
configuration.setLocale(sLocale);
wrapper.applyOverrideConfiguration(configuration);
}
}
public static void updateConfig(Application app, Configuration configuration) {
if(sLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
//Wrapping the configuration to avoid Activity endless loop
Configuration config = new Configuration(configuration);
config.locale = sLocale;
Resources res = app.getBaseContext().getResources();
res.updateConfiguration(config, res.getDisplayMetrics());
}
}
}
Đã thêm mã này vào Ứng dụng
public class App extends Application {
public void onCreate(){
super.onCreate();
LocaleUtils.setLocale(new Locale("iw"));
LocaleUtils.updateConfig(this, getBaseContext().getResources().getConfiguration());
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocaleUtils.updateConfig(this, newConfig);
}
}
Mã trong hoạt động
public class BaseActivity extends AppCompatActivity {
public BaseActivity() {
LocaleUtils.updateConfig(this);
}
}
Câu trả lời của Alex Volovoy chỉ hoạt động với tôi nếu đó là phương pháp onCreate của hoạt động.
Câu trả lời hoạt động trong tất cả các phương thức là trong một luồng khác
Thay đổi ngôn ngữ lập trình trong Android
Đây là sự thích ứng của mã
Resources standardResources = getBaseContext().getResources();
AssetManager assets = standardResources.getAssets();
DisplayMetrics metrics = standardResources.getDisplayMetrics();
Configuration config = new Configuration(standardResources.getConfiguration());
config.locale = new Locale(languageToLoad);
Resources defaultResources = new Resources(assets, metrics, config);
Hy vọng rằng nó sẽ giúp.
Hãy lưu ý rằng giải pháp này bằng cách sử dụng updateConfiguration sẽ không hoạt động nữa với bản phát hành Android M sắp ra mắt trong một vài tuần. Cách mới để thực hiện việc này hiện đang sử dụng applyOverrideConfigurationphương thức từ ContextThemeWrapper
xem tài liệu API
Bạn có thể tìm thấy giải pháp đầy đủ của tôi ở đây kể từ khi tôi tự mình đối mặt với vấn đề: https://stackoverflow.com/a/31787201/2776572
Có một số bước mà bạn nên thực hiện
Trước tiên, bạn cần thay đổi ngôn ngữ cấu hình của bạn
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = new Locale(language);
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
Thứ hai, nếu bạn muốn các thay đổi của mình áp dụng trực tiếp vào bố cục có thể nhìn thấy, bạn có thể cập nhật trực tiếp các chế độ xem hoặc bạn chỉ có thể gọi Activity.recreate () để khởi động lại hoạt động hiện tại.
Và bạn cũng phải kiên trì thay đổi vì sau khi người dùng đóng ứng dụng của bạn thì bạn sẽ mất thay đổi ngôn ngữ.
Tôi đã giải thích giải pháp chi tiết hơn trên bài đăng trên blog của tôi Thay đổi ngôn ngữ lập trình trong Android
Về cơ bản, bạn chỉ cần gọi LocaleHelper.onCreate () trên lớp ứng dụng của mình và nếu bạn muốn thay đổi ngôn ngữ một cách nhanh chóng, bạn có thể gọi LocaleHelper.setLocale ()
Điều này hoạt động khi tôi nhấn nút để thay đổi ngôn ngữ văn bản trong TextView của tôi. (String.xml trong thư mục value-de)
String languageToLoad = "de"; // your language
Configuration config = getBaseContext().getResources().getConfiguration();
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
recreate();
Thêm lớp LocaleHelper
public class LocaleHelper{
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
String lang = getPersistedData(context, Locale.getDefault().getLanguage());
return setLocale(context, lang);
}
public static Context onAttach(Context context, String defaultLanguage) {
String lang = getPersistedData(context, defaultLanguage);
return setLocale(context, lang);
}
public static String getLanguage(Context context) {
return getPersistedData(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
persist(context, language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
}
return updateResourcesLegacy(context, language);
}
private static String getPersistedData(Context context, String defaultLanguage) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}
private static void persist(Context context, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.apply();
}
@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLayoutDirection(locale);
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}
Trong hoạt động hoặc đoạn
Context context = LocaleHelper.setLocale(this, App.getSharedPre().getLanguage());
Resource resources = context.getResources();
Bây giờ SetText trên mỗi văn bản
TextView tv = findViewById(R.id.tv);
tv.setText(resources.getString(R.string.tv));
tương tự như phiên bản đã được chấp nhận nhưng phiên bản 2017 và đã thêm khởi động lại (không khởi động lại, đôi khi Hoạt động tiếp theo vẫn hiển thị tiếng Anh):
// Inside some activity...
private void changeDisplayLanguage(String langCode) {
// Step 1. Change the locale in the app's configuration
Resources res = getResources();
android.content.res.Configuration conf = res.getConfiguration();
conf.setLocale(currentLocale);
createConfigurationContext(conf);
// Step 2. IMPORTANT! you must restart the app to make sure it works 100%
restart();
}
private void restart() {
PackageManager packageManager = getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(getPackageName());
ComponentName componentName = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName);
mainIntent.putExtra("app_restarting", true);
PrefUtils.putBoolean("app_restarting", true);
startActivity(mainIntent);
System.exit(0);
}
activity.recreate()3) bối cảnh được trả về tôi nghĩ phải được sử dụng để lấy tài nguyên
Trước tiên, bạn tạo các giá trị tên thư mục - "Tên ngôn ngữ" như tiếng Hin-ddi hơn là viết "hi" và sao chép tên tệp chuỗi tương tự trong thư mục này và thay đổi giá trị không thay đổi tham số sau khi đặt mã bên dưới trong nút hành động của bạn, v.v.
Locale myLocale = new Locale("hi");
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
Intent refresh = new Intent(Home.this, Home.class);
startActivity(refresh);
finish();
conf.localekhông được dùng nữa
private void setLanguage(String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration config = new Configuration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
config.setLocale(locale);
} else {
config.locale = locale;
}
getResources().updateConfiguration(config,
getResources().getDisplayMetrics());
}
Ví dụ: chúng tôi đặt ngôn ngữ tiếng Anh:
Configuration config = GetBaseContext().getResources().getConfiguration();
Locale locale = new Locale("en");
Locale.setDefault(locale);
config.locale = locale;
GetBaseContext().getResources().updateConfiguration(config,
GetBaseContext().getResources().getDisplayMetrics());
Xin vui lòng, chỉ nhớ điều này hoạt động nếu ngôn ngữ được tìm thấy trong hệ thống Thiết bị, không chỉ trong ứng dụng
Để được hỗ trợ tiếng Ả Rập / RTL
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(updateBaseContextLocale(newBase));
}
public Context updateBaseContextLocale(Context context) {
String language = SharedPreference.getInstance().getValue(context, "lan");//it return "en", "ar" like this
if (language == null || language.isEmpty()) {
//when first time enter into app (get the device language and set it
language = Locale.getDefault().getLanguage();
if (language.equals("ar")) {
SharedPreference.getInstance().save(mContext, "lan", "ar");
}
}
Locale locale = new Locale(language);
Locale.setDefault(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
updateResourcesLocale(context, locale);
return updateResourcesLocaleLegacy(context, locale);
}
return updateResourcesLocaleLegacy(context, locale);
}
@TargetApi(Build.VERSION_CODES.N)
private Context updateResourcesLocale(Context context, Locale locale) {
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}