Androidダイナミックテーブルレイアウト - ビューを追加する例外ILLEGALSTATEEXCEPTION(子供にはすでに親がいます)

StackOverflow https://stackoverflow.com/questions/4156869

質問

必要なTableLayoutsの数としてJavaでレイアウトを作成することは、DesignTimeとしては知られていません。

私は得ます IllegalStateException 削除するように言ってください View (現在の親から)私が電話するとき、それを別の親に割り当てる前に createPlayerTables()

例外は、このループの最初の行でスローされます。imageViewsのリストから最初のタブローにImageViewを追加しようとすると:

for (int i = 0; i < 3; i++) {
    tableRowsLst.get(0).addView((ImageView) imageViewsLst.get(i));
    tableRowsLst.get(1).addView((ImageView) imageViewsLst.get(i+3));
}

エラーは、ImageViewが持っていることを示唆しています すでにビューグループに追加されています, 、しかし、以下のコードを見ると、新しいImageViewsを作成し、エラーが発生する行のビューグループにのみ追加するため、なぜ失敗しているのかわかりません。

// List<ImageView> imageViewsLst = new ...
// List<TableRow> tableRowsLst = new ...

/**
* Initialises the TableLayouts, one per player
*/ 
private TableLayout createPlayerTables(int playerNum) {
    ...

    for (int i = 0; i < 6; i++) {
        imageViewsLst.add(new ImageView(this));
        ...
    }

    for (int i = 0; i < 3; i++) {
        tableRowsLst.add(new TableRow(this));
        ...
    }

    for (int i = 0; i < 3; i++) {
        tableRowsLst.get(0).addView((ImageView) imageViewsLst.get(i));
        tableRowsLst.get(1).addView((ImageView) imageViewsLst.get(i+3));
    }

    ...
}
役に立ちましたか?

解決

このループで:

for (int i = 0; i < 3; i++){
   tableRowsLst.add(new TableRow(this));
   tableRowsLst.get(i).setLayoutParams(
       new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, dipToPixels(55)));
   tableRowsLst.get(i).setOrientation(LinearLayout.HORIZONTAL);
}

新しい追加を続けています TableRowstableRowsLst, 、しかし、あなたは常に最初の3つの要素のみを使用します。

ループの前にリストをクリアします:

tableRowsLst.clear();

他のヒント

この例ではそうではありませんが、この問題の別の一般的な原因は正しく利用していないことです onCreateDialog()onPrepareDialog(). 。 onCreateDialog() 一度だけ呼ばれ、ここで行われたものはすべて持続します。レイアウトに動的コンテンツを追加する場合 (Dialog), 、おそらく使いたいです onPrepareDialog() 作成後は、各ディスプレイの前に発生します。から引用する Androidドキュメント:

ダイアログが表示される前に、AndroidはOnpreparedialog(int、ダイアログ)をonpreparedialogでオプションのコールバックメソッドも呼び出します。このメソッドを定義するダイアログのプロパティを開くたびに変更する場合。このメソッドは、ダイアログが開かれるたびに呼び出されますが、OnCreateDialog(INT)は、ダイアログが最初に開かれたときにのみ呼び出されます。 onpreparedialog()を定義しない場合、ダイアログは開かれた前と同じままです。このメソッドは、oncreatedialog()で作成したダイアログオブジェクトとともに、ダイアログのIDにも渡されます。

ああ!さて、いくつかの虚偽が始まった後、ここに問題があります。

imageViewsList メンバー変数です。 CreatePlayErtablesを呼び出すたびに6つのビューを追加し、毎回最初の6つのビューを使用します。最初のパス(プレーヤー0)、問題ありません。セカンドパス(プレーヤー1):ブーム。

オプション1)それらを保存しないでください。指定されたコードはそれらを必要としませんが、それはすべてのベースをどんなストレッチでもカバーしていません。テーブルの列からそれらを掘り出して、ピンチでキャストすることができます。

オプション2)ImageViewSlistへのアクセスをオフセットします playerNum * 6 (これはそうします == imageViewsList.size() いつ createPlayerTables() 最初に呼ばれます)

友好的なアドバイス:いくつかの異なる方法で問題を見つけることができたかもしれません:

  • tableerow.add()への各呼び出しの前にオブジェクトIDを使用してlog.d()は、2番目のパスで使用された同じオブジェクトIDがすぐに例外が続きます。
  • 便利なダンディデバッガーのコードを介して踏み込んでいます。はい、それはこの場合に何が起こっているのかを把握するためにステップスルーするための多くのコードです。いくつかの異なるブレークポイントにより、CreatePlayErtables()へのどの呼び出しがスローしているかを簡単に確認できるようになり、スローするときにのみCPT()に足を踏み入れることができました。

バグを理解するたびに「これをキャッチするために何ができたのか」と自問すると、デバッグスキルが大幅に向上します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top