Подтвердить что ты не робот

Форматирование форматирования RTL не работает для приложения

Я пытаюсь добавить поддержку языка RTL в моем приложении (особенно на арабском прямо сейчас). Я тоже буду поддерживать английский. Что я сделал:

  • Установите minSdkVersion на 17
  • Добавлен android:supportsRtl="true" для моего тега приложения в AndroidManifest.xml
  • Поменял мои левые/правые атрибуты на начало/конец

Сначала я внес эти изменения вручную, затем я использовал пункт меню Android Studio "Refactor → Add RTL Support Where возможный...".

При предварительном просмотре файлов макета я вижу, что предварительный просмотр RTL правильно отражает пользовательский интерфейс; однако даже когда я использую "Force Layout Direction", мое приложение не отображает RTL-макет. Системный интерфейс перевернут, так что эта опция работает в целом.

Что еще нужно сделать, чтобы показать макет RTL? Я надеюсь, что упустил что-то очевидное. Я тестирую это на эмуляторе API 21.

Обновить

Я унаследовал часть этого кода. Возможно, что-то переопределяет настройку и переводит ее в режим LTR. Я сделал тестовое приложение, чтобы проверить режим RTL, и он работал нормально. Какой код может привести к тому, что параметр "Force RTL Layout Direction" будет проигнорирован (или переопределен)?

Обновление 2

Я проверил, что языковой стандарт устанавливается правильно, и это так. Я также проверил конфигурацию, и ldrtl установлен. Я проверил в подписанном файле APK, что android:supportsRtl сделал это и ни один из файлов макета не было android:layoutDirection="ltr". Я даже пытался вручную положить android:layoutDirection="rtl" чтобы попытаться заставить макет зеркально android:layoutDirection="rtl", но это тоже не сработало. '

Обновление 3

Я добавил еще одно действие в проект, сделал его активностью запуска и убедился, что оно не связано с каким-либо существующим кодом. Это подкласс Activity. Проблема все еще существует. Так что теоретически это проблема конфигурации. Как я уже сказал, я проверил файл AndroidManifest.xml и все файлы макетов, которые были сгенерированы, а также внесены изменения в поддержку RTL и макет. Что может быть не так с конфигурацией?

4b9b3361

Ответ 1

Самая неясная ошибка за всю историю. Как я уже упоминал в этом вопросе, большая часть этого кода была унаследована. В результате возникла проблема с побитовым оператором, которая портила флаги для приложения. &= использовался вместо & чтобы проверить, был ли установлен флаг.

Как отмечается в комментариях, код был взят из примера в блоге разработчиков Android, в котором объясняется, почему многие другие столкнулись с этой проблемой. Я подал отчет об ошибке, и с тех пор сообщение в блоге было тихо обновлено. Вот оригинальный код, который я удалил &=. Не используйте следующий код как есть. Вам нужно изменить &= на &:

isDebuggable = (appContext.getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE) != 0;

Ответ 2

Попробуйте это...

  • Создайте класс для поддержания состояния глобального приложения.

    public class YourGlobalClass extends Application {
    
      @Override
      public void onCreate() {
      updateLanguage(this, null);
      super.onCreate();
      }
    
    public static void updateLanguage(Context ctx, String lang) {
    
     Configuration cfg = new Configuration();
     LocalSharedManager manager = new LocalSharedManager(ctx);
     String language = manager.GetValueFromSharedPrefs("force_locale");
    
        if (TextUtils.isEmpty(language) && lang == null) {
           cfg.locale = Locale.getDefault();
           String tmp_locale = "";
           tmp_locale = Locale.getDefault().toString().substring(0, 2);
           manager.SaveValueToSharedPrefs("force_locale", tmp_locale);
    
       } else if (lang != null) {
           cfg.locale = new Locale(lang);
           manager.SaveValueToSharedPrefs("force_locale", lang);
    
       } else if (!TextUtils.isEmpty(language)) {
           cfg.locale = new Locale(language);
       }
       ctx.getResources().updateConfiguration(cfg, null);
      }
    
    }
    
  • Укажите глобальный класс в тэг AndroidManifest.xml, который приведет к созданию экземпляра класса с сохраненной локалью, когда будет создан процесс для вашего приложения/пакета. Например, android:name="com.your.package.YourGlobalClass" android:supportsRtl="true"

  • Создайте следующие два метода в вашем MainActivity.java(где угодно).

    public class MainActivity extends ActionBarActivity{
    
       .......
    
       // Implement OnclickListener for english_locale button
       findViewById(R.id.english_locale).setOnClickListener(new OnClickListener()
         {
    
            @Override
            public void onClick(View v)
            {
                changeEnglish();
            }
         });
    
        // Implement OnclickListener for arabic_locale button
        findViewById(R.id.arabic_locale).setOnClickListener(new OnClickListener()
           {
    
              @Override
              public void onClick(View v)
               {
                  changeArabic();
                }
           });
    
        /**
        * Method that Update UI for Arabic locale.
        */
        public void changeArabic() {
             new AsyncTask<Void, Void, Void>() {
    
             @Override
             protected Void doInBackground(Void... params) {
                  String app_locale = "ar";
                  Locale locale = new Locale(app_locale);
                  Locale.setDefault(locale);
    
                  //Configuration to query the current layout direction.
                  Configuration config = new Configuration();
                  config.locale = locale;
                  getResources().updateConfiguration(config,
                    getResources().getDisplayMetrics());
                  Bidi bidi = new Bidi(app_locale,
                    Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
                  bidi.isRightToLeft();
                  YourGlobalClass.updateLanguage(getActivity(), "ar");
    
                  //Refreshing current fragment
    
                  Intent i = getActivity().getIntent();
                  startActivity(i);
                  getActivity().finish();
               return null;
              }
    
           }.execute();
         }
    
            /**
            * Method that Update UI for Default(English) locale.
            */
          public void changeEnglish() {
    
              new AsyncTask<Void, Void, Void>() {
    
              @Override
              protected Void doInBackground(Void... params) {
                  String app_locale = "en";
                  Locale locale = new Locale(app_locale);
                  Locale.setDefault(locale);
    
                  //Configuration to query the current layout direction.
                  Configuration config = new Configuration();
                  config.locale = locale;
                  getResources().updateConfiguration(config,
                    getResources().getDisplayMetrics());
                  Bidi bidi = new Bidi(app_locale,
                    Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
                  bidi.isLeftToRight();
                  YourGlobalClass.updateLanguage(getActivity(), "en");
    
                  //Refreshing current fragment
                  Intent i = getActivity().getIntent();
                  startActivity(i);
                  getActivity().finish();
    
              return null;
              }
    
           }.execute();
         }
    
       ......
      //MainActivity end
    }
    
  • Счастливое кодирование...

Ответ 3

добавьте эту строку кода в самый верх метода onCreate (перед super и setContentView) всех ваших действий:

getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);

и убедитесь, что у вас supportRtl равен True в манифесте.

android:supportsRtl="true"