是否有可能在使用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");
        }
    }
}

其他回答

如果你想在你的应用中保持语言变化,你必须做两件事。

首先,创建一个base Activity,让你所有的Activity都从下面扩展:

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()与上面相同。

这是所有! 我希望这能帮助到一些人。

这段代码真的可以工作:

fa = 波斯语,en = 英语

注意:语言代码不能有“-”,必须是2个小写字母

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

2021年6月更新(Kotlin):

class Main : Activity() {
    // Called when the activity is first created.
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        val config = resources.configuration
        val lang = "fa" // your language code
        val locale = Locale(lang)
        Locale.setDefault(locale)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
            config.setLocale(locale)
        else
            config.locale = locale

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
            createConfigurationContext(config)
        resources.updateConfiguration(config, resources.displayMetrics)

        this.setContentView(R.layout.main)
    }
}

这是有可能的。您可以设置区域。然而,我不建议这样做。我们在早期阶段尝试过,基本上是在对抗这个系统。

我们对改变语言有同样的要求,但决定接受UI应该与手机UI相同的事实。它是通过设置locale工作,但太bug了。根据我的经验,每次输入活动(每个活动)时都必须设置它。这里是一个代码,如果你仍然需要这个(再次强调,我不推荐)

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);

如果您有特定于语言的内容-您可以根据设置更改它。


2020年3月26日更新

    public static void setLocale(Activity activity, String languageCode) {
        Locale locale = new Locale(languageCode);
        Locale.setDefault(locale);
        Resources resources = activity.getResources();
        Configuration config = resources.getConfiguration();
        config.setLocale(locale);
        resources.updateConfiguration(config, resources.getDisplayMetrics());
    }

注意:语言代码不能有“-”,必须是2个小写字母

如果你正在使用片段,并且你想在Android中以编程方式更改应用程序语言,请使用此方法

  public void setLocale(Activity activity, String languageCode) {
    Locale locale = new Locale(languageCode);
    Locale.setDefault(locale);
    Resources resources = activity.getResources();
    Configuration config = resources.getConfiguration();
    config.setLocale(locale);
    resources.updateConfiguration(config, resources.getDisplayMetrics());
     SettingsFragment settingsFragment = new SettingsFragment();
     FragmentManager fragmentManager = requireActivity().getSupportFragmentManager();
     FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    activity.overridePendingTransition(0,0);
     fragmentTransaction.replace(R.id.main, settingsFragment).commit();
}

这样叫它

setLocale(requireActivity(),"fr");

只需要用你的片段名改变SettingsFragment,在你调用方法的地方,这基本上是刷新布局来获得视图上的新字符串 如果你想在另一个类上设置这个方法只需像这样添加context

public void setLocale(Activity activity, String languageCode,Context context) {
    Locale locale = new Locale(languageCode);
    Locale.setDefault(locale);
    Resources resources = activity.getResources();
    Configuration config = resources.getConfiguration();
    config.setLocale(locale);
    resources.updateConfiguration(config, resources.getDisplayMetrics());
    SettingsFragment settingsFragment = new SettingsFragment();
    FragmentManager fragmentManager = ((AppCompatActivity) context).getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    activity.overridePendingTransition(0,0);
    fragmentTransaction.replace(R.id.main, settingsFragment).commit();
}

阿拉伯语/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; }