0

在 Java 中创建所需的 TableLayout 数量的布局并不称为设计时。

当我打电话时,我收到一条IllegalStateException告诉我View在将其分配给另一个父级之前删除(从它的当前父级)createPlayerTables()

当我尝试将 ImageView 从 ImageViews 列表添加到第一个 TableRow 时,此循环的第一行会引发异常:

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已经添加到 ViewGroup,但是看到下面的代码,我创建了新的 ImageView,并且我只将它们添加到 ViewGroup 中出错的行,所以我不确定它为什么会失败.

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

    ...
}
4

3 回答 3

4

在这个循环中:

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

你只是不断地添加 new TableRowstableRowsLst但你总是只使用前三个元素。

清除循环前的列表:

tableRowsLst.clear();
于 2010-11-11T17:28:32.193 回答
2

尽管在此示例中并非如此,但此问题的另一个常见原因是未正确使用onCreateDialog()onPrepareDialog(). onCreateDialog()只调用一次,这里所做的任何事情都将持续存在。如果您正在向布局添加动态内容(Dialog),您可能希望使用onPrepareDialog()在创建之后但在每次显示之前发生的内容。引用Android 文档

在显示对话框之前,Android 还会调用可选的回调方法 onPrepareDialog(int, Dialog)。如果您想在每次打开对话框时更改对话框的任何属性,请定义此方法。每次打开对话框时都会调用此方法,而 onCreateDialog(int) 仅在第一次打开对话框时调用。如果您没有定义 onPrepareDialog(),则对话框将保持与上次打开时相同。此方法还传递对话框的 ID,以及您在 onCreateDialog() 中创建的 Dialog 对象。

于 2011-05-02T05:46:47.210 回答
1

啊哈!好的,在几次错误的开始之后,问题就来了。

imageViewsList是成员变量。每次调用 createPlayerTables 时都会添加 6 个视图,然后每次都使用前 6 个。第一次传球(玩家 0),没问题。第二次传球(玩家 1):繁荣。

选项1)不要保存它们。给定的代码不需要它们,尽管它并没有涵盖所有的基础。您可以将它们从表格行中挖掘出来,然后在紧要关头将它们扔掉。

选项 2) 偏移您对 imageViewsList 的访问权限playerNum * 6(第一次调用== imageViewsList.size()createPlayerTables()

友好的建议:您可以通过几种不同的方式找到问题:

  • 在每次调用 TableRow.add() 之前带有对象 ID 的 Log.d() 将显示第二遍中使用的相同对象 ID,紧随其后的是您的异常。
  • 在 Handy Dandy Debugger 中单步调试您的代码。是的,为了弄清楚在这种情况下发生了什么,需要逐步执行大量代码。几个不同的断点可以更容易地查看对 createPlayerTables() 的哪个调用正在抛出,并允许您仅在它要抛出时才进入 cpt()。

每次你发现一个错误时问自己“我能做些什么来捕捉这个”,这将极大地提高你的调试技能。

于 2010-11-11T17:27:09.940 回答