Восстановление иерархии представлений из сохраненного состояния не восстанавливает представления, добавленные программно

Я пытаюсь сохранить и восстановить иерархию представления, состоящую из таблицы кнопок. Количество строк и кнопок таблицы, требуемых в таблице, не известно до времени выполнения и программно добавляется в раздутый макет XML в моем Activity"s onCreate(Bundle) метод. Мой вопрос: можно ли сохранить и восстановить финальную таблицу, используя реализацию сохранения / восстановления представления Android по умолчанию?

Пример моей текущей попытки приведен ниже. На начальном этапе таблица строится, как и ожидалось. Когда действие уничтожено (вращением устройства), перестроенный вид показывает только пустой TableLayout без детей

XML-файл, указанный в setContentView(int) включает в себя, среди прочего, пустой TableLayout что кнопки добавлены к.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Setup this activity's view.
    setContentView(R.layout.game_board);

    TableLayout table = (TableLayout) findViewById(R.id.table);

    // If this is the first time building this view, programmatically
    // add table rows and buttons.
    if (savedInstanceState == null) {
        int gridSize = 5;
        // Create the table elements and add to the table.
        int uniqueId = 1;
        for (int i = 0; i < gridSize; i++) {
            // Create table rows.
            TableRow row = new TableRow(this);
            row.setId(uniqueId++);
            for (int j = 0; j < gridSize; j++) {
                // Create buttons.
                Button button = new Button(this);
                button.setId(uniqueId++);
                row.addView(button);
            }
            // Add row to the table.
            table.addView(row);
       }
    }
}

Насколько я понимаю, Android сохраняет состояние представлений до тех пор, пока им назначен идентификатор, и восстанавливает представления при воссоздании действия, но сейчас, похоже, происходит повторная разметка макета XML и ничего более. При отладке кода я могу подтвердить, что onSaveInstanceState() называется на каждом Button в таблице, но onRestoreInstanceState(Parcelable) не является.

3 ответа

Решение

После поиска по исходному коду Activity, View а также ViewGroupЯ узнал, что программно добавленные виды должны быть программно добавлены и каждый раз им присваивается один и тот же идентификатор. onCreate(Bundle) называется. Это верно независимо от того, создает ли оно представление в первый раз или воссоздает представление после уничтожения действия. Сохраненное состояние экземпляра программно добавленных представлений затем восстанавливается во время вызова Activity.onRestoreInstanceState(Bundle), Самый простой ответ на приведенный выше код - просто убрать проверку savedInstanceState == null,

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    // Setup this activity's view. 
    setContentView(R.layout.game_board); 

    TableLayout table = (TableLayout) findViewById(R.id.table); 

    int gridSize = 5;
    // Create the table elements and add to the table. 
    int uniqueId = 1; 
    for (int i = 0; i < gridSize; i++) { 
        // Create table rows. 
        TableRow row = new TableRow(this); 
        row.setId(uniqueId++);
        for (int j = 0; j < gridSize; j++) {
            // Create buttons.
            Button button = new Button(this);
            button.setId(uniqueId++);
            row.addView(button);
        }
        // Add row to the table.
        table.addView(row);
   }
}

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

Как программно назначить идентификатор для представления?

Эта строка воссоздает пустой макет:

setContentView(R.layout.game_board);

Кроме того, вы назначаете одинаковые идентификаторы для строк и кнопок. Вы должны были использовать один счетчик для строк и кнопок:

    int idCounter = 1;
    for (int i = 0; i < gridSize; i++) {
        TableRow row = new TableRow(this);
        row.setId(idCounter++);
        for (int j = 0; j < gridSize; j++) {
            Button button = new Button(this);
            button.setId(idCounter++);
            row.addView(button);
        }
        ...
    }
Другие вопросы по тегам