Проблема локализации Android: не все элементы в макете корректно обновляются при переключении локалей - PullRequest
13 голосов
/ 22 декабря 2010

Вот проблема: когда у меня в фоновом режиме выполняется действие, и я переключаю языковые стандарты и снова переключаюсь в приложение, все обновляется ... ЗА ИСКЛЮЧЕНИЕМ флажков и переключателей, для которых установлен атрибут «android: id».

Если флажки и переключатели не имеют атрибута "android: id", тогда они обновляются, OK.Другие поля не имеют этой проблемы, имеют ли они атрибут «android: id» или нет.

Каков наилучший способ убедиться, что все в моей беговой деятельности обновляется всякий раз, когда изменяется языковой стандарт?

Шаги для воспроизведения:

1) Создайте проект «Hello, Android» в Eclipse.2) В основном макете определите два флажка:

<CheckBox android:text="@string/checkbox" android:id="@+id/CheckBox01" android:layout_width="wrap_content" android:layout_height="wrap_content"></CheckBox>
<CheckBox android:text="@string/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content"></CheckBox>

3) Создайте два файла strings.xml: один в разделе «values» и один в разделе «values-es».

4)Создайте следующую строку в «values»:

<string name="checkbox">English</string>

5) Создайте следующую строку в «values-es»

<string name="checkbox">español</string>

6) Установите для устройства значение «English»

7) Запустите приложение на эмуляторе или на любом устройстве (проверено на HTC G1).

8) Наблюдайте.На обоих флажках указано «Английский».

9) Нажмите «Домой», чтобы вернуться в меню и оставить приложение работающим в фоновом режиме.

10) Перейти к настройкам.Переключите язык на «español»

11) Нажмите и удерживайте «Домой». Вернитесь к приложению.

Ожидаемый результат:

Оба флажка говорят «español»

Фактический результат:

Первый флажок говорит «английский»

Второй флажок говорит «español»

Похоже, что флажок с атрибутом «android: id»не обновляется должным образом. Флажок без атрибута «android: id» работает должным образом.

Ответы [ 4 ]

8 голосов
/ 30 апреля 2013

Причина проблемы в том, что CompoundButton.onSaveInstanceState() вызывает setFreezesText(true) и, таким образом, сохраняет и восстанавливает текст.

Простое решение заключается в использовании подкласса:

public class CheckBoxNoPersistentText extends CheckBox {

    public CheckBoxNoPersistentText(final Context context) {
        super(context);
    }

    public CheckBoxNoPersistentText(final Context context, final AttributeSet attrs) {
        super(context, attrs);
    }

    public CheckBoxNoPersistentText(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void onRestoreInstanceState(final Parcelable state) {

        final CharSequence text = getText(); // the text has been resolved anew

        super.onRestoreInstanceState(state); // this restores the old text

        setText(text); // this overwrites the restored text with the newly resolved text

    }
}
5 голосов
/ 22 декабря 2010

Это увлекательная ошибка. Я могу воспроизвести его на своем Nexus One.

Похоже, что в реализации по умолчанию onSaveInstanceState(). Если вы переопределите это как неиспользуемое (не подключайтесь к суперклассу), проблема исчезнет.

Значение по умолчанию onSaveInstanceState() должно обрабатывать такие вещи, как состояние флажка, но они, должно быть, это испортили и тоже сохраняют текст.

Итак, у вас есть пара обходных путей:

  1. Переопределить onSaveInstanceState() и не связываться с суперклассом. Это, однако, исключает любое автоматическое сохранение состояния, которое вы обычно получаете.
  2. В onRestoreInstanceState() (... я думаю ...) после цепочки к суперклассу вызовите setText() для ваших затронутых виджетов с соответствующим строковым ресурсом, чтобы вернуть его обратно к правильному значению.

Я постараюсь продолжить эту работу завтра, когда у меня будет шанс. Я хочу проверить исходный код и, возможно, зарегистрировать его как проблему.

0 голосов
/ 28 марта 2013

Этот билет 2 года предлагает обходной путь не использования android: id, поэтому я исправил эту проблему, используя похожий макет:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- KEEP THIS ALWAYS THE FIRST because it dosen't have
        an android:id as a workaround of this bug
        https://code.google.com/p/android/issues/detail?id=13252
        -->
    <RadioButton xmlns:android="http://schemas.android.com/apk/res/android" />

    <!-- other elements -->

</RelativeLayout>

Так что теперь, чтобы получить RadioButtonЯ использую что-то вроде этого:

private RadioButton getButton(RelativeLayout layout) {
    RadioButton button = null;
    if (layout.getChildCount() != 0) {
        button = (RadioButton) layout.getChildAt(0);
    }
    return button;
}

Так что я могу установить свойства программно.

0 голосов
/ 22 декабря 2010

Если некоторые из них находятся в памяти, они не изменятся.Если вы перезагрузите телефон, переустановите приложение или хотя бы полностью убьете приложение, оно будет работать нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...