2012-03-15 22 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を持っているとして、ビューの状態を保存し、活動が再作成されたときにビューを復元することですが、今、XMLレイアウトと何をreinflateているようですもっと。コードをデバッグすると、テーブル内の各ButtononSaveInstanceState()が呼び出されていることを確認できますが、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()'のように)ビューを追加すると、内容が復元するには遅すぎることに注意してください。 –

+0

基本的に、アクティビティに複数のビューとフラグメントが生成されている場合は、各ID、各ビュー、各タイプのFragmentを覚えておく必要がありますか?このチョイスの理由は何ですか?アプリが殺されたときのようにすべてを復活させるのはなぜですか? –

+0

onCreateでビューを追加できない場合はどうなりますか? –

0

ビューがID付きで動作する場合は、作成時に各ボタンにテーブル内のIDを付けてみましょう。それが動作するかどうかを確認します。

setContentView(R.layout.game_board); 

以外にも、あなたが行とボタンに等しいidを割り当てます

How can I assign an ID to a view programmatically?

+1

上記のコードを確認してください。すべての行とボタンには、すでにプログラムによってIDが追加されています。 – happydude

0

この行は空のレイアウトを再作成します。あなたは、行とボタンの両方のために1つのカウンターを使用している必要があります。

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

関連する問題