Восстановление иерархии представлений из сохраненного состояния не восстанавливает представления, добавленные программно
Я пытаюсь сохранить и восстановить иерархию представления, состоящую из таблицы кнопок. Количество строк и кнопок таблицы, требуемых в таблице, не известно до времени выполнения и программно добавляется в раздутый макет 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);
}
...
}