2012-03-15 35 views
10

我試圖保存和還原包含按鈕表的視圖層次結構。表中所需的錶行和按鈕的數量在運行時纔是已知的,並且可以通過程序將其添加到我的ActivityonCreate(Bundle)方法中的膨脹的xml佈局中。我的問題是:可以使用Android的默認視圖保存/恢復實現來保存和恢復最終表格嗎?從保存狀態還原視圖層次不會還原以編程方式添加的視圖

我當前嘗試的一個示例如下。在初始運行時,表格按預期構建。當活動被破壞(通過旋轉設備)時,重建視圖僅顯示沒有孩子的空TableLayout

setContentView(int)中引用的xml文件除其他外,還包括將按鈕添加到的空的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的,只要他們有分配給他們的ID保存視圖狀態,而當活動重新恢復的意見,但現在它似乎reinflate的XML佈局並沒有什麼更多。在調試代碼時,我可以確認onSaveInstanceState()在表中的每個Button上都被調用,但onRestoreInstanceState(Parcelable)不是。

回答

11

通過爲ActivityViewViewGroup源代碼搜索後,我才知道,編程方式添加的意見必須以編程方式添加和分配的每個相同的ID時間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); 
    } 
} 
+3

沒錯:框架保存並恢復每個視圖的狀態,但不保存存在的視圖。這就是爲什麼無論'savedInstanceState'是否爲null,您都必須調用'setContentView()',同樣的,您必須在onCreate()(或onCreateView())中爲片段創建任何動態視圖。請注意,如果稍後添加視圖(例如,在'onStart()')中,那麼爲恢復它們的內容太遲了。 – 2012-09-27 09:12:11

+0

所以基本上,如果我的Activity有幾個通過用戶交互生成的視圖和片段,我需要記住每個ID,每個視圖和每種類型的片段?這種選擇的原因是什麼?他們爲什麼不簡單地恢復一切,就像應用程序被殺時一樣? – 2015-03-11 15:34:46

+0

如果在onCreate期間無法添加視圖,該怎麼辦? – 2015-03-11 15:35:45

0

該行重新創建一個空的佈局:

setContentView(R.layout.game_board); 

此外,您分配等於ID的行和按鈕。你應該用一個計數器行和兩個按鈕:

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); 
     } 
     ... 
    } 
+0

感謝您的迴應,上面的代碼已被編輯,以顯示爲所有編程添加的視圖分配唯一的ID具有相同的結果。我應該如何處理在第一個和後續的onCreate()調用中設置內容視圖? – happydude 2012-03-15 14:40:33

相關問題