是否有可能在使用Android资源的同时以编程方式改变应用程序的语言?

如果不是,是否可以用特定的语言请求资源?

我想让用户改变应用程序的语言从应用程序。


当前回答

我也面临着同样的问题。在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");
        }
    }
}

其他回答

根据这篇文章。您需要下载那篇文章中引用的LocaleHelper.java。

Create MyApplication class that will extends Application Override attachBaseContext() to update language. Register this class in manifest. public class MyApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(LocaleHelper.onAttach(base, "en")); } } <application android:name="com.package.MyApplication" .../> Create BaseActivity and override onAttach() to update language. Needed for Android 6+ public class BaseActivity extends Activity { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(LocaleHelper.onAttach(base)); } } Make all activities on your app extends from 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; } }

阿拉伯语/RTL支持

您必须通过- attachBaseContext()更新您的语言设置。 对于android版本N及以上,您必须使用createconfigationcontext () & updateConfiguration() -否则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; }

唯一完全适合我的解决方案是结合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);         
    }
}

对我来说,最好的解决办法是: https://www.bitcaal.com/how-to-change-the-app-language-programmatically-in-android/

package me.mehadih.multiplelanguage;

import androidx.appcompat.app.AppCompatActivity;

import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;

import java.util.Locale;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setApplicationLocale("az"); // short name of language. "en" for English
        setContentView(R.layout.activity_main);

    }

    private void setApplicationLocale(String locale) {
        Resources resources = getResources();
        DisplayMetrics dm = resources.getDisplayMetrics();
        Configuration config = resources.getConfiguration();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            config.setLocale(new Locale(locale.toLowerCase()));
        } else {
            config.locale = new Locale(locale.toLowerCase());
        }
        resources.updateConfiguration(config, dm);
    }
}

对于Android 7.0牛轧糖(或更低),请遵循这篇文章:

在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());
}