【问题标题】:createConfigurationContext not working on API level <26 to change language programmaticallycreateConfigurationContext 无法在 API 级别 <26 上以编程方式更改语言
【发布时间】:2020-01-18 17:00:24
【问题描述】:

我已阅读有关在运行时更改应用内语言的所有内容。目前一切都适用于 API 26+27+28+29(是的,我已经测试了所有这些),并在 API 25 及更低版本开始中断。 Now the only thing I know that happened in API level 26 was that application and activities no longer share the same resources (aka the top level resources) by default. And also that updateConfiguration for Resources gets deprecated in favor of createConfigurationContext in API 25

但是,这确实给了我零线索。

这是我的代码:

public class BaseApp extends MultiDexApplication { //for MinSDK < 21, otherwise "extends Application"

@Override
public void onCreate() {
    LocaleHelper.updateResources(this);
    super.onCreate();
}

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(LocaleHelper.updateResources(base));
    MultiDex.install(this); /* Needed as per (@link MultiDexApplication) */

}

@Override
public void onConfigurationChanged(Configuration config) {
    super.onConfigurationChanged(config);
    LocaleHelper.updateResources(this);
}

基础活动:

public abstract class BaseActivity extends AppCompatActivity {

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(LocaleHelper.updateResources(base));
}

助手类:

class LocaleHelper {

static Context updateResources(Context context) {
    Resources resources = context.getResources();
    Configuration config = new Configuration(resources.getConfiguration());
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    String lang = preferences.getString(Constants.PREF_KEY_LOCALE_OVERRIDE, Constants.PREF_VALUE_LOCALE_SYSTEM);
    Locale locale = new Locale(lang);

    if (Build.VERSION.SDK_INT >= 17) {
        config.setLocale(locale);
        context = context.createConfigurationContext(config);
    } else {
        config.locale = locale;
        resources.updateConfiguration(config, resources.getDisplayMetrics());
    }
    return context;
}

【问题讨论】:

  • 这个答案对我有用check this
  • 现在面临同样的问题..有什么更新吗??
  • 有什么解决办法吗?
  • 如我所见,您可能忘记调用 Locale.setDefault(locale)
  • 我终于自己解决了这个问题。 github.com/YarikSOffice/LanguageTest/issues/6 1.1.0 appcompat有问题,所以我已经更新到下一个版本(现在是1.2.0-rc01)

标签: android configuration locale android-resources android-context


【解决方案1】:

这是 AndroidX 的 AppCompat 实现的一个已知错误。 该错误在版本 1.0.0 中:'androidx.appcompat:appcompat:1.1.0' 我确认它适用于库的 1.2.0 版本。

【讨论】:

    【解决方案2】:

    为什么不使用https://github.com/YarikSOffice/lingver 库。

    除了那个库之外,我还必须添加这一行才能重新启动我的设置活动。

    UtilLanguage.setLanguage(activity, position); //This is the line where I used library   
    activity.recreate();
    

    对于之前的活动(设置活动的Backstack),我存储了现有语言并检查了resume方法的更改以更新我的主要活动;

    @Override
    public void onResume() {
    
        if (selectedLanguageIndex != appPreferences.getPreferredApplicationLanguageIndex()) {
            recreate();
        }
    }
    

    【讨论】:

      【解决方案3】:

      试试这个:

       private Context updateResources(Context context, String language) {
          Locale locale = new Locale(language);
          Locale.setDefault(locale);
      
          Resources res = context.getResources();
          Configuration config = new Configuration(res.getConfiguration());
          if (Utility.isAtLeastVersion(N)) {
              setLocaleForApi24(config, locale);
              context = context.createConfigurationContext(config);
          } else if (Utility.isAtLeastVersion(JELLY_BEAN_MR1)) {
              config.setLocale(locale);
              context = context.createConfigurationContext(config);
          } else {
              config.locale = locale;
              res.updateConfiguration(config, res.getDisplayMetrics());
          }
          return context;
      }
      
      @RequiresApi(api = N)
      private void setLocaleForApi24(Configuration config, Locale target) {
          Set<Locale> set = new LinkedHashSet<>();
          // bring the target locale to the front of the list
          set.add(target);
      
          LocaleList all = LocaleList.getDefault();
          for (int i = 0; i < all.size(); i++) {
              // append other locales supported by the user
              set.add(all.get(i));
          }
      
          Locale[] locales = set.toArray(new Locale[0]);
          config.setLocales(new LocaleList(locales));
      }
      

      并查看这篇文章:https://proandroiddev.com/change-language-programmatically-at-runtime-on-android-5e6bc15c758

      【讨论】:

        猜你喜欢
        • 2012-01-13
        • 1970-01-01
        • 1970-01-01
        • 2016-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多