เป็นไปได้ไหมที่จะเปลี่ยนภาษาของแอปแบบเป็นโปรแกรมในขณะที่ยังใช้ทรัพยากร Android อยู่
ถ้าไม่เป็นไปได้หรือไม่ที่จะขอทรัพยากรในภาษาใดภาษาหนึ่ง?
ฉันต้องการให้ผู้ใช้เปลี่ยนภาษาของแอพจากแอพ
เป็นไปได้ไหมที่จะเปลี่ยนภาษาของแอปแบบเป็นโปรแกรมในขณะที่ยังใช้ทรัพยากร Android อยู่
ถ้าไม่เป็นไปได้หรือไม่ที่จะขอทรัพยากรในภาษาใดภาษาหนึ่ง?
ฉันต้องการให้ผู้ใช้เปลี่ยนภาษาของแอพจากแอพ
คำตอบ:
มันเป็นไปได้. คุณสามารถกำหนดสถานที่ อย่างไรก็ตามฉันจะไม่แนะนำ เราได้ลองในช่วงแรก ๆ แล้วมันเป็นการต่อสู้กับระบบโดยทั่วไป
เรามีข้อกำหนดแบบเดียวกันสำหรับการเปลี่ยนภาษา แต่ตัดสินใจที่จะตัดสินว่า UI ควรเหมือนกับ UI ของโทรศัพท์ มันทำงานผ่านการตั้งค่าสถานที่เกิดเหตุ แต่ก็บั๊กซีเกินไป และคุณต้องตั้งค่าทุกครั้งที่คุณป้อนกิจกรรม (แต่ละกิจกรรม) จากประสบการณ์ของฉัน นี่คือรหัสถ้าคุณยังต้องการสิ่งนี้ (อีกครั้งฉันไม่แนะนำ)
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);
หากคุณมีเนื้อหาภาษาเฉพาะ - คุณสามารถเปลี่ยนฐานที่ตั้ง
อัปเดตในวันที่ 26 มีนาคม 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()
ซึ่งสามารถใช้เพื่อห่อบริบทเริ่มต้นด้วยการกำหนดค่าเฉพาะสถานที่แล้วเรียกgetResources
ใช้โดยไม่ต้องอัปเดตการกำหนดค่าบนวัตถุทรัพยากรด้วยตนเอง
conf.setLayoutDirection(locale)
คุณสามารถแทนที่ด้วยconf.locale = new Locale(...))
มันภายในจะเรียกconf.setLocale(new Locale(...))
setLayoutDirection
รหัสนี้ใช้งานได้จริง:
fa = เปอร์เซีย, en = อังกฤษ
ป้อนรหัสภาษาของคุณในlanguageToLoad
ตัวแปร:
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.updateConfiguration
วิธีการ ฉันได้เยื้องรหัสเพื่อให้ชัดเจนยิ่งขึ้น
ฉันกำลังมองหาวิธีที่จะเปลี่ยนภาษาของระบบโดยทางโปรแกรม ในขณะที่ฉันเข้าใจอย่างถ่องแท้ว่าแอปพลิเคชันทั่วไปไม่ควรทำเช่นนั้นและแทน:
ไม่จำเป็นต้องเปลี่ยนภาษาของระบบโดยทางโปรแกรม
นี่คือ API ที่ไม่มีเอกสารดังนั้นจึงไม่ควรใช้สำหรับแอปพลิเคชันตลาด / ผู้ใช้ปลายทาง!
ยังไงก็ตามฉันพบวิธีแก้ปัญหา:
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_CONFIGURATION
เท่านั้นที่จะได้รับอนุญาตจากแอปที่เซ็นชื่อด้วยปุ่มดำเนินการ
หากคุณต้องการเปลี่ยนภาษาของแอปทั้งหมดของคุณคุณต้องทำสองสิ่ง
ขั้นแรกสร้างกิจกรรมพื้นฐานและทำให้กิจกรรมทั้งหมดของคุณขยายจากนี้:
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);
}
}
โปรดทราบว่าฉันบันทึกภาษาใหม่ใน sharedPreference
ประการที่สองสร้างส่วนขยายของแอปพลิเคชันเช่นนี้:
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);
}
}
}
โปรดทราบว่า getLocale () มันเหมือนกับข้างต้น
นั่นคือทั้งหมด! ฉันหวังว่านี่จะช่วยให้ใครบางคน
Application
มันคืออะไรและใช้อย่างไร mobomo.com/2011/05/how-to-use-application-object-of-android
configuration.locate
เลิกใช้แล้ว setLocale ต้องการ API 17+ และ updateConfiguration เลิกใช้แล้ว
ตามที่ บทความนี้ คุณจะต้องดาวน์โหลดLocaleHelper.java
การอ้างอิงในบทความนั้น
MyApplication
คลาสที่จะขยายApplication
attachBaseContext()
เพื่ออัปเดตภาษาลงทะเบียนคลาสนี้โดยชัดแจ้ง
public class MyApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
}
}
<application
android:name="com.package.MyApplication"
.../>
สร้างBaseActivity
และแทนที่onAttach()
เพื่ออัปเดตภาษา จำเป็นสำหรับ Android 6+
public class BaseActivity extends Activity {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
}
ทำให้กิจกรรมทั้งหมดในแอพของคุณขยายออก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;
}
}
เพียงแค่เพิ่มชิ้นส่วนพิเศษที่ทำให้ฉันสะดุด
ในขณะที่คำตอบอื่น ๆ ทำงานได้ดีกับ "de" เช่น
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());
ข้างต้นจะไม่ทำงานกับ"fr_BE"
สถานที่ตัวอย่างเช่นดังนั้นมันจะใช้values-fr-rBE
โฟลเดอร์หรือคล้ายกัน
ต้องการการเปลี่ยนแปลงเล็กน้อยในการทำงานกับ "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();
แทนที่จะสร้างConfiguration
อินสแตนซ์ใหม่ มีประโยชน์สำหรับการใช้ใหม่หรือไม่
ฉันเปลี่ยนเป็นภาษาเยอรมันสำหรับแอปของฉันเริ่มต้นเอง
นี่คือรหัสที่ถูกต้องของฉัน ทุกคนต้องการใช้สิ่งนี้เหมือนกันสำหรับฉัน .. (วิธีเปลี่ยนภาษาใน Android โดยทางโปรแกรม)
รหัสของฉัน:
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);
}
ฉันรู้ว่ามันสายที่จะตอบ แต่ผมพบว่า บทความนี้ที่นี่ ซึ่งอธิบายกระบวนการทั้งหมดได้เป็นอย่างดีและให้รหัสที่มีโครงสร้างที่ดีแก่คุณ
คลาส Helper Helper:
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;
}
}
คุณต้องแทนที่ attachBaseContext และโทร LocaleHelper.onAttach () เพื่อเริ่มต้นการตั้งค่า locale ในแอปพลิเคชันของคุณ
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"));
}
}
สิ่งที่คุณต้องทำคือการเพิ่ม
LocaleHelper.onCreate(this, "en");
ทุกที่ที่คุณต้องการเปลี่ยนสถานที่
createConfigurationContext
ที่เป็นประโยชน์
สร้างคลาสขยายApplication
และสร้างวิธีการคงที่ 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);
}
}
การใช้งานในกิจกรรม:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApp.setLocaleFa(MainActivity.this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
}
เปลี่ยนภาษาอย่างเป็นระบบใน Android
คำตอบเก่า
ซึ่งรวมถึงการสนับสนุน 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());
}
ทางออกเดียวที่ทำงานได้อย่างสมบูรณ์สำหรับฉันคือการรวมกันของรหัสของ Alex Volovoy กับกลไกการรีสตาร์ทแอพพลิเคชั่น:
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()
ฉันกำลังเผชิญกับปัญหาเดียวกัน บน GitHub ฉันพบห้องสมุด Android-LocalizationActivityห้องสมุดที่ใช้
ห้องสมุดนี้ทำให้การเปลี่ยนภาษาของแอพของคุณเป็นเรื่องง่ายอย่างที่คุณเห็นในตัวอย่างโค้ดด้านล่าง ตัวอย่างโครงการรวมถึงรหัสตัวอย่างด้านล่างและข้อมูลเพิ่มเติมสามารถดูได้ที่หน้า GitHub
LocalizationActivity ขยาย AppCompatActivity ดังนั้นคุณสามารถใช้เมื่อคุณใช้ Fragments
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");
}
}
}
เวลาสำหรับการอัปเดตเนื่องจาก
ก่อนอื่นรายการที่เลิกใช้แล้วกับ API ที่เลิกใช้แล้ว:
configuration.locale
(API 17)updateConfiguration(configuration, displaymetrics)
(API 17)สิ่งที่ไม่มีคำตอบที่ถูกต้องเมื่อเร็ว ๆ นี้คือการใช้วิธีการใหม่นี้มีอากาศที่เหมาะสมคือการใช้วิธีการใหม่
createConfigurationContext เป็นวิธีการใหม่สำหรับ updateConfiguration
บางคนใช้มันแบบสแตนด์อโลนเช่นนี้:
Configuration overrideConfiguration = ctx.getResources().getConfiguration();
Locale locale = new Locale("en_US");
overrideConfiguration.setLocale(locale);
createConfigurationContext(overrideConfiguration);
... แต่นั่นไม่ได้ผล ทำไม? เมธอดส่งคืนบริบทซึ่งใช้เพื่อจัดการการแปล Strings.xml และรีซอร์สที่แปลเป็นภาษาท้องถิ่นอื่น ๆ (รูปภาพ, เลย์เอาต์, อะไรก็ตาม)
การใช้งานที่เหมาะสมเป็นเช่นนี้:
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();
หากคุณเพิ่งคัดลอกและวางลงใน IDE ของคุณคุณอาจเห็นคำเตือนว่า API ต้องการให้คุณกำหนดเป้าหมาย API 17 ขึ้นไป สิ่งนี้สามารถแก้ไขได้โดยการใส่ไว้ในวิธีการและเพิ่มคำอธิบายประกอบ@TargetApi(17)
แต่เดี๋ยวก่อน. แล้ว API ที่เก่ากว่าจะเป็นอย่างไร
คุณต้องสร้างวิธีอื่นโดยใช้ updateConfiguration โดยไม่มีหมายเหตุประกอบ 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);
คุณไม่จำเป็นต้องกลับบริบทที่นี่
ตอนนี้การจัดการสิ่งเหล่านี้อาจเป็นเรื่องยาก ใน API 17+ คุณต้องสร้างบริบท (หรือทรัพยากรจากบริบทที่สร้างขึ้น) เพื่อรับทรัพยากรที่เหมาะสมตามการโลคัลไลเซชัน คุณจัดการกับสิ่งนี้ได้อย่างไร
นี่คือวิธีที่ฉันทำ:
/**
* 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;
}
รหัสนี้ทำงานโดยมีวิธีการหนึ่งที่ทำให้การเรียกไปยังวิธีการที่เหมาะสมตาม API ใด นี่คือสิ่งที่ฉันทำกับการโทรที่เลิกใช้จำนวนมาก (รวมถึง Html.fromHtml) คุณมีวิธีหนึ่งที่ใช้ในการโต้แย้งที่จำเป็นซึ่งจะแยกออกเป็นหนึ่งในสองวิธี (หรือสามหรือมากกว่า) และส่งกลับผลลัพธ์ที่เหมาะสมตามระดับ API มีความยืดหยุ่นเนื่องจากคุณไม่จำเป็นต้องตรวจสอบหลายครั้งวิธี "รายการ" จะช่วยคุณได้ วิธีการเข้าที่นี่คือsetLanguage
คุณต้องใช้บริบทที่ส่งคืนเมื่อคุณได้รับทรัพยากร ทำไม? ฉันได้เห็นคำตอบอื่น ๆ ที่นี่ที่ใช้ createConfigurationContext และไม่ใช้บริบทที่ส่งคืน หากต้องการให้มันทำงานอย่างนั้นต้องเรียกการกำหนดค่าใหม่ ซึ่งเลิกใช้แล้ว ใช้บริบทที่ส่งกลับโดยวิธีการรับทรัพยากร
ตัวอย่างการใช้งาน :
ตัวสร้างหรือบางที่คล้ายกัน:
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)
จากนั้นไม่ว่าคุณต้องการรับทรัพยากรจากที่ไหน:
String fromResources = ctx.getString(R.string.helloworld);
การใช้บริบทอื่น ๆ (ในทางทฤษฎี) จะทำลายสิ่งนี้
AFAIK คุณยังต้องใช้บริบทของกิจกรรมเพื่อแสดงข้อความโต้ตอบหรือ Toasts เพื่อที่คุณสามารถใช้อินสแตนซ์ของกิจกรรม (ถ้าคุณอยู่นอก)
และสุดท้ายใช้recreate()
กิจกรรมเพื่อรีเฟรชเนื้อหา ปุ่มลัดที่ไม่ต้องสร้างความตั้งใจในการรีเฟรช
ถ้าคุณเขียน
android:configChanges="locale"
ในทุกกิจกรรม (ในไฟล์ Manifest) Activity
แล้วจะต้องตั้งมันทุกครั้งที่คุณป้อนไม่
configChanges
ใช้แฮ็คเพื่อรักษาสถานะของกิจกรรมไว้ในการหมุน / etc
Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration config = context.getResources().getConfiguration();
config.setLocale(locale);
context.createConfigurationContext(config);
การอัปเดตที่สำคัญ:
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
โปรดทราบว่าใน SDK> = 21 คุณต้องโทรหา'Resources.updateConfiguration ()'มิฉะนั้นทรัพยากรจะไม่ได้รับการอัปเดต
Context ctx = createConfigurationContext(args);
และรับทรัพยากรจากนั้น
/*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
configuration
ควรตั้งค่าในแต่ละactivity
ก่อนการตั้งค่าเนื้อหา -this.setContentView(R.layout.main);
activity.recreate()
ตอนแรกสร้าง multi string.xml สำหรับภาษาอื่น จากนั้นใช้โค้ดบล็อกนี้ในonCreate()
วิธี:
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);
นี่คือรหัสที่เหมาะกับฉัน:
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);
}
}
ที่มา: ที่นี่
ไม่มีวิธีแก้ปัญหาที่ระบุไว้ที่นี่ช่วยฉันได้
ภาษาไม่ได้เปิดบน Android> = 7.0 ถ้า AppCompatDelegate.setDefaultNightMode (AppCompatDelegate.MODE_NIGHT_YES)
LocaleUtils นี้ใช้ได้ดี: 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());
}
}
}
เพิ่มรหัสนี้ในแอปพลิเคชัน
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);
}
}
รหัสในกิจกรรม
public class BaseActivity extends AppCompatActivity {
public BaseActivity() {
LocaleUtils.updateConfig(this);
}
}
คำตอบของ Alex Volovoy ใช้ได้กับฉันถ้ามันอยู่ในวิธีการสร้างกิจกรรม
คำตอบที่ใช้งานได้ในวิธีการทั้งหมดอยู่ในหัวข้ออื่น
เปลี่ยนภาษาโดยใช้โปรแกรมใน Android
นี่คือการดัดแปลงของรหัส
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);
หวังว่ามันจะช่วย
โปรดทราบว่าการใช้โซลูชันนี้updateConfiguration
จะไม่ทำงานอีกต่อไปเมื่อมีการเปิดตัวAndroid Mในอีกไม่กี่สัปดาห์ วิธีใหม่ในการทำเช่นนี้คือตอนนี้ใช้applyOverrideConfiguration
วิธีจากContextThemeWrapper
ดูเอกสาร API
คุณสามารถหาวิธีแก้ปัญหาทั้งหมดของฉันที่นี่ตั้งแต่ฉันประสบปัญหาด้วยตัวเอง: https://stackoverflow.com/a/31787201/2776572
มีขั้นตอนบางอย่างที่คุณควรใช้
ก่อนอื่นคุณต้องเปลี่ยนภาษาของการกำหนดค่าของคุณ
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = new Locale(language);
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
ประการที่สองหากคุณต้องการให้การเปลี่ยนแปลงของคุณนำไปใช้โดยตรงกับโครงร่างที่มองเห็นได้คุณสามารถอัปเดตมุมมองได้โดยตรงหรือคุณสามารถเรียกกิจกรรมได้เพียงสร้าง recreate () เพื่อเริ่มกิจกรรมปัจจุบันใหม่
และคุณต้องยืนยันการเปลี่ยนแปลงของคุณเพราะหลังจากผู้ใช้ปิดแอปพลิเคชันของคุณคุณจะสูญเสียการเปลี่ยนแปลงภาษา
ฉันอธิบายโซลูชันที่มีรายละเอียดเพิ่มเติมเกี่ยวกับโพสต์บล็อกของฉันเปลี่ยนภาษาโดยทางโปรแกรมใน Android
โดยทั่วไปคุณเพียงแค่เรียก LocaleHelper.onCreate () ในคลาสแอปพลิเคชันของคุณและหากคุณต้องการเปลี่ยนสถานที่เกิดเหตุได้ทันทีคุณสามารถโทรหา LocaleHelper.setLocale ()
สิ่งนี้ทำงานเมื่อฉันกดปุ่มเพื่อเปลี่ยนภาษาข้อความของ TextView ของฉัน (strings.xml ในโฟลเดอร์ values-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();
เพิ่มคลาส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;
}
}
ในกิจกรรมหรือชิ้นส่วน
Context context = LocaleHelper.setLocale(this, App.getSharedPre().getLanguage());
Resource resources = context.getResources();
ตอนนี้ SetText ในทุกข้อความ
TextView tv = findViewById(R.id.tv);
tv.setText(resources.getString(R.string.tv));
คล้ายกับคำตอบที่ยอมรับ แต่รุ่น 2017 และเพิ่มการรีสตาร์ท (โดยไม่ต้องรีสตาร์ทบางครั้งกิจกรรมต่อไปยังแสดงภาษาอังกฤษ):
// 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) บริบทที่ส่งคืนฉันคิดว่าจะต้องใช้เพื่อให้ได้ทรัพยากร
ก่อนอื่นคุณสร้างค่าชื่อไดเรกทอรี - "ชื่อภาษา" เช่นภาษาฮินดีกว่าเขียน "hi" และคัดลอกชื่อไฟล์สตริงเดียวกันในไดเรกทอรีนี้และค่าการเปลี่ยนแปลงไม่เปลี่ยนพารามิเตอร์หลังจากตั้งค่าด้านล่างรหัสในการกระทำของคุณเช่นปุ่ม ฯลฯ ...
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.locale
เลิกใช้แล้ว
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());
}
ในตัวอย่างเราตั้งค่าภาษาอังกฤษ:
Configuration config = GetBaseContext().getResources().getConfiguration();
Locale locale = new Locale("en");
Locale.setDefault(locale);
config.locale = locale;
GetBaseContext().getResources().updateConfiguration(config,
GetBaseContext().getResources().getDisplayMetrics());
โปรดจำไว้ว่าใช้งานได้เฉพาะในกรณีที่พบภาษาในระบบอุปกรณ์เท่านั้นไม่เพียง แต่ในแอปพลิเคชัน
สำหรับการสนับสนุนภาษาอารบิก / 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;
}