2017-06-13 8 views
1

実行時にアプリのロケールを変更しようとしていました。 APIレベル24以下のAndoridでは正常に動作していますが、APIレベル24以上では、レイアウトの方向はロケールによって変化しません。 以下は、実行時にロケールを変更するためのコードです。 ロケール変更時の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")); 
    } 
を追加したコードであるように私はLocaleHelperクラスを使用していました

これで、ロケールを英語からウルドゥー語に変更すると、言語は変更されますが、レイアウトの方向は期待通りに変わりません。再度ウルドゥー語をクリックすると、レイアウトの方向が変わります(2回目の試行)。以下はrefrence

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

を解決するには助けてくださいされています最初の更新。 API 25でテスト

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

とそれがうまく働いている:私は以下のようなActivityonAttachedToWindowメソッドをオーバーライドして、問題を解決しました。現時点ではこのアプローチの副作用についてはわかりませんが、注意してください。それにもかかわらず、私はそれがあなたが探しているものだと思います。

blog postも更新し、よりエレガントで包括的なコードを反映させます。

+0

ありがとう..それは私のために働いた –

関連する問題