Android dynamische Tabellenlayout - Hinzufügen von Ansichten werfen Ausnahme Illegal (Kind hat bereits einen Elternteil)

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

Frage

ein Layout in Java wie die Anzahl der TableLayouts ist erforderlich, als Entwurfszeit nicht bekannt ist.

ich eine IllegalStateException erhalte mich zu sagen, die View zu entfernen (von seinen aktuell Eltern), bevor sie an einem anderen Elternteil zuweisen, wenn ich rufe createPlayerTables()

Die Ausnahme in der ersten Zeile in dieser Schleife geworfen wird, wenn ich versuche, eine Image aus der Liste des ImageViews zur ersten TableRow hinzuzufügen:

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

Der Fehler lässt vermuten, dass die Image hat bereits hinzugefügt, um eine Viewgroup , aber den Code unten zu sehen, schaffe ich neue ImageViews, und ich sie nur an der Linie zu einer Viewgroup hinzufügen, dass es Fehler bei , so dass ich bin mir nicht sicher, warum es scheitern.

// 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));
    }

    ...
}
War es hilfreich?

Lösung

In dieser Schleife:

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);
}

Sie halten gerade neuen TableRows zu tableRowsLst hinzufügen, aber Sie immer nur die ersten drei Elemente verwendet werden.

Löschen Sie die Liste vor der Schleife:

tableRowsLst.clear();

Andere Tipps

Obwohl dies nicht der Fall ist in diesem Beispiel eine weitere häufige Ursache für dieses Problem korrekt nicht onCreateDialog() und onPrepareDialog() verwendet. Die onCreateDialog() wird nur einmal aufgerufen und alles, was hier getan wird bestehen bleiben. Wenn Sie dynamische Inhalte zu einem Layout (Dialog) hinzufügen, möchten Sie wahrscheinlich onPrepareDialog() verwenden, die geschehen wird nach erstellen, aber vor jeder Anzeige. Ein Zitat aus der Android Dokumentation :

Bevor das Dialogfeld angezeigt wird, Android ruft auch die optionale Callback-Methode onPrepareDialog (int, Dialog). Definieren Sie diese Methode, wenn Sie alle Eigenschaften des Dialogs jedes Mal ändern möchten sie geöffnet wird. Dieses Verfahren wird jedes Mal, wenn ein Dialog geöffnet genannt, während onCreateDialog (int) ist nur das erste Mal, wenn ein Dialog geöffnet wird aufgerufen. Wenn Sie nicht onPrepareDialog () definieren, dann wird der Dialog die gleichen bleiben, wie es die früheren Zeit war es geöffnet wurde. Diese Methode wird auch der Dialog des ID übergeben, zusammen mit dem Dialog Objekt, das Sie in onCreateDialog () erstellt wurde.

Aha! Okay, nach ein paar Fehlstarts, hier ist das Problem.

imageViewsList ist eine Membervariable. Du fügst 6 Ansichten jedes Mal, wenn createPlayerTables rufen, dann wird die erste 6 jedes Mal verwenden. Erster Durchgang (Spieler 0), kein Problem. Zweiter Durchgang (Spieler 1):. Boom

Option 1) speichere sie nicht. Der angegebene Code braucht sie nicht, obwohl das nicht alle die Grundlagen von einer Strecke abdeckt. Man könnte sich der Tabellenzeilen raben und warf sie in einer Prise.

Option 2) Offset Ihren Zugriff auf imageViewsList von playerNum * 6 (was == imageViewsList.size() wenn createPlayerTables() wird zuerst genannt)

Friendly Rat: Sie könnten das Problem in ein paar verschiedene Möglichkeiten gefunden haben:

  • Log.d () mit dem Objekt-ID vor jedem Aufruf TableRow.add () die gleiche Objekt-ID haben würde sofort von Ihrer Ausnahme, im zweiten Durchgang verwendet, offenbart.
  • Stepping durch den Code in das Handy Dandy Debugger. Ja, das ist eine Menge Code zu Schritt durch, um herauszufinden, was in diesem Fall würde. Ein paar andere Bruchstellen wäre es leichter gemacht, um zu sehen nur die Anruf createPlayerTables () war zu werfen und erlaubt Ihnen Schritt in cpt (), wenn es würde werfen.

Fragen sich jedes Mal, „was hätte ich diese zu fangen getan“ Sie haben einen Fehler herausgefunden wird unermesslich Ihre Debugging-Fähigkeiten verbessern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top