0

I have written this code which tries to add Table Rows (which contain Text Views) inside a Table Layout. This is done in a loop. I get this error:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.testant/com.test.testant.products}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

Can I somehow override the removeView() on parent? If I can't how can the removeView() be incorporated inside my code?

products.java

public class products extends Activity{
private DataBaseManager dataBase;

//put the table name and column in constants
public static final String TABLE_NAME_PRODUCTS = "products";

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    setContentView(R.layout.products);
    TableLayout tl = (TableLayout) findViewById(R.id.prodTable);
    TableRow tr = (TableRow) findViewById(R.id.prodRow);



    //creates and open the database so we can use it
    dataBase = DataBaseManager.instance();

    Cursor cursor = dataBase.select("SELECT * FROM " + TABLE_NAME_PRODUCTS);
    while (cursor.moveToNext()){

        tl.addView(tr);


    }

}

products.xml

<TableLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:id="@+id/prodTable">

        <TableRow
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:clickable="false"
            android:id="@+id/prodRow">

            <TextView
                android:layout_width="0dp"
                android:layout_height="fill_parent"
                android:layout_weight=".08"
                android:textColor="#fff"
                android:id="@+id/prodCodeView"
                android:clickable="true" />
            <TextView
                android:layout_width="0dp"
                android:layout_height="fill_parent"
                android:layout_weight=".30"
                android:textColor="#fff"
                android:id="@+id/prodNameView"
                android:clickable="true" />
            <TextView
                android:layout_width="0dp"
                android:layout_height="fill_parent"
                android:layout_weight=".05"
                android:textColor="#fff"
                android:id="@+id/prodMUView" />
            <TextView
                android:layout_width="0dp"
                android:layout_height="fill_parent"
                android:layout_weight=".10"
                android:textColor="#fff"
                android:id="@+id/prodPriceView" />
            <TextView
                android:layout_width="0dp"
                android:layout_height="fill_parent"
                android:layout_weight=".05"
                android:textColor="#fff"
                android:id="@+id/prodVATView" />
            <TextView
                android:layout_width="0dp"
                android:layout_height="fill_parent"
                android:layout_weight=".05"
                android:textColor="#fff"
                android:id="@+id/prodIDView" />
        </TableRow>
    </TableLayout>

3 Answers 3

2

You are trying to add the same TableRow again and again a Table. Which is causing exception:

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

You should create a new TableRow in a loop itself

Code snippet:

Cursor cursor = dataBase.select("SELECT * FROM " + TABLE_NAME_PRODUCTS);
while (cursor.moveToNext()){
    TableRow tr = new TableRow(this);
    //set width and height using layout params
    tl.addView(tr);
}

Hope it helps.

Sign up to request clarification or add additional context in comments.

6 Comments

findViewByID() doesn't create a new object, it only returns what already exists - another reference to the same instance, which wouldn't improve the situation very much, here.
Right. Missed that he was using findViewById while copying. Thanks :)
Well now it is working, but the new table is does not look like the one I have in products.xml. I want it to contain those text views and have the same layout.
@user2315641 You can put the TextViews in TableRow programatically, too.
This beats the whole purpose of the whole process. I would like the rows with the text views created in each cycle to be populated by data from the database. Basically there would be no point on creating the rows in products.xml.
|
1

you have to create TableRow dynamically

Cursor cursor = dataBase.select("SELECT * FROM " + TABLE_NAME_PRODUCTS);
while (cursor.moveToNext()){
  TableRow tr=new TableRow(context); // either create it here or get reference from xml file.
       // setting layoutparam to tr and then add it to table layout tl;
    tl.addView(tr);


}

you can not add same TableRow more than one.

1 Comment

Do I use it like this: TableRow.LayoutParams(R.id.prodRow, AttributeSet attrs)? What do I put to AttributeSet attrs? Will it add the included TextViews too?
1

Each of your rows needs to be instances of their own. The way you implemented it above, they are just one and the same. That cannot work. You need to inflate the table-row in the loop using a layout-inflater or create the objects manually.

Using an inflater could look like this:

Cursor cursor = dataBase.select("SELECT * FROM " + TABLE_NAME_PRODUCTS);
while (cursor.moveToNext()){
    TableRow tr = (TableRow) View.inflate(this, R.id.prodRow, tl);
    // now get the cells from the row by findViewByID()
    // and fill them with your data...
    // This addView might be redundant. If you have your rows twice in your table
    // just remove the addView() line, as it might be done by the inflate() method,
    // I am not sure of that by heart.
    tl.addView(tr);
}

1 Comment

I've already made some progress by myself, but this answer filled some blanks I had. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.