2017-06-13 79 views
1

我试图在运行时更改应用的语言环境。它在低于API级别24的Andorid中工作正常。但在API级别24或更高级别中,布局方向不会根据语言环境而改变。 下面是在运行时更改语言环境的代码。我已经使用LocaleHelper类,如下语言环境变化时API 24及更高版本中的Android RTL问题

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); 
     Log.d("LocaleHelper", "language : "+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; 
     configuration.setLayoutDirection(locale); 
     resources.updateConfiguration(configuration, resources.getDisplayMetrics()); 

     return context; 
    } 
} 

而下面是我在活动课

public class MainActivity extends AppCompatActivity { 
    @BindView(R.id.titleTextView) 
    TextView mTitleTextView; 
    @BindView(R.id.descTextView) 
    TextView mDescTextView; 
    @BindView(R.id.aboutTextView) 
    TextView mAboutTextView; 
    @BindView(R.id.toTRButton) 
    Button mToTRButton; 
    @BindView(R.id.toENButton) 
    Button mToENButton; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     ButterKnife.bind(this); 

     setTitle(getString(R.string.main_activity_toolbar_title)); 
    } 

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

    @OnClick(R.id.toTRButton) 
    public void onChangeToTRClicked() { 
     updateViews("ur"); 
    } 

    @OnClick(R.id.toENButton) 
    public void onChangeToENClicked() { 
     updateViews("en"); 
    } 

    private void updateViews(String languageCode) { 
     Context context = LocaleHelper.setLocale(this, languageCode); 
     Resources resources = context.getResources(); 

     mTitleTextView.setText(resources.getString(R.string.main_activity_title)); 
     mDescTextView.setText(resources.getString(R.string.main_activity_desc)); 
     mAboutTextView.setText(resources.getString(R.string.main_activity_about)); 
     mToTRButton.setText(resources.getString(R.string.main_activity_to_tr_button)); 
     mToENButton.setText(resources.getString(R.string.main_activity_to_en_button)); 

     setTitle(resources.getString(R.string.main_activity_toolbar_title)); 
     this.recreate(); 
    } 
} 

在我的应用程序类使用的代码我已经添加了下面的代码

@Override 
    protected void attachBaseContext(Context base) { 
     super.attachBaseContext(LocaleHelper.onAttach(base, "en")); 
    } 

现在,当我将语言环境从英语更改为乌尔都语时,语言会发生变化,但布局方向不会按预期更改。当我再次点击乌尔都语,然后布局方向改变(第二次尝试)。下面是做参考

enter image description here

App language changes but layout direction does not changed

Now layout direction is RTL but it should be LTR for English language

在解决问题

+0

是您的问题与给定的答案解决? – Gunhan

回答

1

的问题请大家帮忙截图似乎是,它不反映在布局方向变化第一次更新。我通过重写的ActivityonAttachedToWindow方法如下面解决了这个问题:

@Override 
public void onAttachedToWindow() { 
    super.onAttachedToWindow(); 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 
     getWindow().getDecorView().setLayoutDirection(
       "ur".equals(LocaleHelper.getLanguage(this)) ? 
       View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR); 
    } 
} 

测试在API 25和它的正常工作。小心,虽然我不确定此时此方法的任何副作用。不过,我认为这是你正在寻找的。

我还会更新blog post以反映更优雅的通用代码。

+0

谢谢..这对我有用 –