为什么我在删除 Android TableRow 的方法上得到 null?

Why am I getting null on a method to delete an Android TableRow?

问题: 我有两个 TableLayouts,每个 TableRow 都有删除行按钮。当调用 deleteTableRows() 方法时,删除 FILES table 的行没有问题,但它失败并显示 null object AUTHOR table 上的错误。我已经调试了几个小时,但无法确定导致问题的 null?我希望有人能看到我看不到的东西。

我做了什么: 我已经用了好几个月了,但我觉得有必要将一个 setupDeleteRowButton 方法分成两个单独的方法,因为我需要独立的方法控制每个 TableLayoutlayoutParam 调整。我想我可以稍后重构。否则,这两种方法实际上是相同的。

我有一个 deleteTableRow() 方法可以从 OnClickListener 调用的 TableLayouts 中删除行。为 TableLayouts 动态创建 TableRows 的两个方法为创建的每一行添加一个基于 tag 的标识符,因此当调用 deleteTableRows() 方法时,将删除正确的行基于 tag 标识符。

发生了什么: 我没有看到任何 null 调试?当我删除 File table 行时,使用您在下面的 deleteTableRows() 方法中看到的标记 - 没问题!当我处理 Author table 时,我在空 object 引用上得到 'java.lang.String java.lang.Object.toString()' - - 但我没看到?使困惑?我检查了 tabletblRowtag 变量的空值,但没有任何空值。

**我已经包含了工作的“文件”版本以与代码的“作者”版本进行比较。我还在学习Android,所以我的方法可能有点笨拙。 TableLayouts 是在 XML activity 处创建的,所有行都是动态添加的...包括 headers.

删除方法 它在 if 语句中失败,此方法由 setup[table]DeleteRowButton() 方法调用

public static void deleteTableRows(TableLayout table, String tag){
    for (int i=1; i < table.getChildCount(); i++){
        TableRow tblRow = (TableRow) table.getChildAt(i);
        if(tblRow.getTag().toString().equals(tag)) {
            table.removeView(tblRow);
            break;
        }
    }
}

我在上面的 if 语句中看到并收到了这些 这是下面错误中的第 187 行和 [= 方法调用中的第 167 行24=] 在下面的代码中

两个 setup[table]DeleteRowButton 方法(OnClickListeners 设置相同,传递唯一标记)- 由 setup[table]TableRow() 方法调用

我不确定我是否对其中任何一个有问题,但“文件”版本对 deleteTableRows() 的调用没有问题,“作者”版本的调用显然有问题?它们都传递 String 标签,因此使用 .toString()

public static Button setupFileDeleteRowButton(Context context, TableLayout table, String tag){
    Button btnDelete = new Button(context);
    TableRow.LayoutParams trLayoutParams = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT);
    trLayoutParams.setMargins(3,3,3,3);
    trLayoutParams.weight = 1;
    trLayoutParams.height =75;
    btnDelete.setLayoutParams(trLayoutParams);
    btnDelete.setBackgroundColor(Color.WHITE);
    btnDelete.setText("-");
    btnDelete.setTypeface(Typeface.DEFAULT,Typeface.BOLD);
    btnDelete.setTextSize(14);
    btnDelete.setGravity(Gravity.CENTER);
    btnDelete.setPadding(5,5,5,5);
    btnDelete.setTag(tag);
    btnDelete.setOnClickListener(v -> {
        String btnTag = btnDelete.getTag().toString();
        deleteTableRows(table, btnTag);
    });
    return btnDelete;
}


public static Button setupAuthorDeleteRowButton(Context context, TableLayout table, String tag){
    Button btnDelete = new Button(context);
    TableRow.LayoutParams trLayoutParams = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT);
    trLayoutParams.setMargins(3,3,3,3);
    trLayoutParams.weight = 0.05f;
    trLayoutParams.height =75;
    btnDelete.setLayoutParams(trLayoutParams);
    btnDelete.setBackgroundColor(Color.WHITE);
    btnDelete.setText("-");
    btnDelete.setTypeface(Typeface.DEFAULT,Typeface.BOLD);
    btnDelete.setTextSize(14);
    btnDelete.setGravity(Gravity.CENTER);
    btnDelete.setPadding(5,5,5,5);
    btnDelete.setTag(tag);
    btnDelete.setOnClickListener(v -> {
        String btnTag = btnDelete.getTag().toString();
        deleteTableRows(table, btnTag);
    });
    return btnDelete;
}

创建和传递 table 和特定标签信息的两种方法(同样,“文件”没有问题,只是“作者”

            row.addView(setupFileDeleteRowButton(context, table, fileName));
            for(int r=1; r < 2; r++){
                row.setTag(fileName);
                row.addView(addRowTextViewToTable(context, fileName, false));
                row.setClickable(true);
            }


            row.addView(setupAuthorDeleteRowButton(context, table, DateTimestampManager.currentTimestamp()));
            for(int r=1; r<5;r++) {
                row.addView(addEditTextToTable(context, ""));
                row.setClickable(true);
                Log.e("BuildTableLayout", "addEditTextToTable");
            }

我找到了解决办法。我仍然不知道为什么以前的设置适用于“FILE”版本而不适用于“AUTHOR”,但此修复程序适用于两者。也就是说,查看 getChildAt(0) 位置确实有意义,因为它始终是按钮位置并接收 setTag。无论如何,这是解决方法。我必须在 tblRow 上包含 .getChildAt(0),然后获取标签并检查。

public static void deleteTableRows(TableLayout table, String tag){
    for (int i=1; i < table.getChildCount(); i++){
        TableRow tblRow = (TableRow) table.getChildAt(i);
        if(tblRow.getChildAt(0).getTag().toString().equals(tag)) {
            table.removeView(tblRow);
            break;
        }
    }
}