I am trying to create a layout where I need to add table rows dynamically. Below is the table layout xml

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/displayLinear"
    android:background="@color/background_df"
    android:orientation="vertical" >

         <TableRow
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/display_row"
            android:layout_marginTop="280dip" >

</TableLayout>

The activity file where rows are being added dynamically is

public void init(){
    menuDB = new MenuDBAdapter(this);
    ll = (TableLayout) findViewById(R.id.displayLinear);

    TableRow row=(TableRow)findViewById(R.id.display_row);
    for (int i = 0; i <2; i++) {

        checkBox = new CheckBox(this);
        tv = new TextView(this);
        addBtn = new ImageButton(this);
        addBtn.setImageResource(R.drawable.add);
        minusBtn = new ImageButton(this);
        minusBtn.setImageResource(R.drawable.minus);
        qty = new TextView(this);
        checkBox.setText("hello");
        qty.setText("10");
        row.addView(checkBox);
        row.addView(minusBtn);
        row.addView(qty);
        row.addView(addBtn);
        ll.addView(row,i);

    }
}

But when I run this, I am getting below error

08-13 16:27:46.437: E/AndroidRuntime(23568): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.roms/com.example.roms.DisplayActivity}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

I understand that this is due to command ll.addView(row,i); but when I remove this its adding all stuff in a single row rather tan creating a new row for next item. I tried with giving index too as row.addView(addBtn,i) but still its not populating correctly. Please advise. Thanks.

Solution 1

Create an init() function and point the table layout. Then create the needed rows and columns.

   public void init() {
            TableLayout stk = (TableLayout) findViewById(R.id.table_main);
            TableRow tbrow0 = new TableRow(this);
            TextView tv0 = new TextView(this);
            tv0.setText(" Sl.No ");
            tv0.setTextColor(Color.WHITE);
            tbrow0.addView(tv0);
            TextView tv1 = new TextView(this);
            tv1.setText(" Product ");
            tv1.setTextColor(Color.WHITE);
            tbrow0.addView(tv1);
            TextView tv2 = new TextView(this);
            tv2.setText(" Unit Price ");
            tv2.setTextColor(Color.WHITE);
            tbrow0.addView(tv2);
            TextView tv3 = new TextView(this);
            tv3.setText(" Stock Remaining ");
            tv3.setTextColor(Color.WHITE);
            tbrow0.addView(tv3);
            stk.addView(tbrow0);
            for (int i = 0; i < 25; i++) {
                TableRow tbrow = new TableRow(this);
                TextView t1v = new TextView(this);
                t1v.setText("" + i);
                t1v.setTextColor(Color.WHITE);
                t1v.setGravity(Gravity.CENTER);
                tbrow.addView(t1v);
                TextView t2v = new TextView(this);
                t2v.setText("Product " + i);
                t2v.setTextColor(Color.WHITE);
                t2v.setGravity(Gravity.CENTER);
                tbrow.addView(t2v);
                TextView t3v = new TextView(this);
                t3v.setText("Rs." + i);
                t3v.setTextColor(Color.WHITE);
                t3v.setGravity(Gravity.CENTER);
                tbrow.addView(t3v);
                TextView t4v = new TextView(this);
                t4v.setText("" + i * 15 / 32 * 10);
                t4v.setTextColor(Color.WHITE);
                t4v.setGravity(Gravity.CENTER);
                tbrow.addView(t4v);
                stk.addView(tbrow);
            }

        }

Call init function in your onCreate method:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        init();
    }

Layout file like:

 <ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#3d455b"
        android:layout_alignParentLeft="true" >

        <HorizontalScrollView
            android:id="@+id/hscrll1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" >

            <RelativeLayout
                android:id="@+id/RelativeLayout1"
                android:layout_width="fill_parent"
                android:layout_gravity="center"
                android:layout_height="fill_parent"
                android:orientation="vertical" >

                <TableLayout
                    android:id="@+id/table_main"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerHorizontal="true" >
                </TableLayout>
            </RelativeLayout>
        </HorizontalScrollView>
    </ScrollView>

Will look like:

Solution 2

You shouldn't be using an item defined in the Layout XML in order to create more instances of it. You should either create it in a separate XML and inflate it or create the TableRow programmaticaly. If creating them programmaticaly, should be something like this:

    public void init(){
    TableLayout ll = (TableLayout) findViewById(R.id.displayLinear);


    for (int i = 0; i <2; i++) {

        TableRow row= new TableRow(this);
        TableRow.LayoutParams lp = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT);
        row.setLayoutParams(lp);
        checkBox = new CheckBox(this);
        tv = new TextView(this);
        addBtn = new ImageButton(this);
        addBtn.setImageResource(R.drawable.add);
        minusBtn = new ImageButton(this);
        minusBtn.setImageResource(R.drawable.minus);
        qty = new TextView(this);
        checkBox.setText("hello");
        qty.setText("10");
        row.addView(checkBox);
        row.addView(minusBtn);
        row.addView(qty);
        row.addView(addBtn);
        ll.addView(row,i);
    }
}

Solution 3

You also can, as Fredigato said, declare a RelativeLayout in a separate Layout file. Then instantiate it using:

for(int i = 0; i < 6; i ++){
LayoutInflater inflater = (LayoutInflater)getApplicationContext().getSystemService
                (Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout row = (RelativeLayout) inflater.inflate(R.layout.table_view,null);
        quizesTableLayout.addView(row,i);
}

In this approach you can easily design one custom row using XML and reuse it.

Now, to be able to change the children views in the instantiated RelativeLayout. You can call row.childAt(index).

So lets say you have a TextView in the RelativeLayout, you can use:

TextView tv = (TextView) row.childAt(0);
tv.setText("Text");

Solution 4

change code of init like following,

public void init(){
    menuDB = new MenuDBAdapter(this);
    ll = (TableLayout) findViewById(R.id.displayLinear);
    ll.removeAllViews()

    for (int i = 0; i <2; i++) {
        TableRow row=(TableRow)findViewById(R.id.display_row);
        checkBox = new CheckBox(this);
        tv = new TextView(this);
        addBtn = new ImageButton(this);
        addBtn.setImageResource(R.drawable.add);
        minusBtn = new ImageButton(this);
        minusBtn.setImageResource(R.drawable.minus);
        qty = new TextView(this);
        checkBox.setText("hello");
        qty.setText("10");
        row.addView(checkBox);
        row.addView(minusBtn);
        row.addView(qty);
        row.addView(addBtn);
        ll.addView(row,i);

    }

Solution 5

Activity
    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TableLayout
            android:id="@+id/mytable"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        </TableLayout>
    </HorizontalScrollView>

Your Class

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_testtable);
    table = (TableLayout)findViewById(R.id.mytable);
    showTableLayout();
}


public  void showTableLayout(){
    Date date = new Date();
    int rows = 80;
    int colums  = 10;
    table.setStretchAllColumns(true);
    table.bringToFront();

    for(int i = 0; i < rows; i++){

        TableRow tr =  new TableRow(this);
        for(int j = 0; j < colums; j++)
        {
            TextView txtGeneric = new TextView(this);
            txtGeneric.setTextSize(18);
            txtGeneric.setText( dateFormat.format(date) + "\t\t\t\t" );
            tr.addView(txtGeneric);
            /*txtGeneric.setHeight(30); txtGeneric.setWidth(50);   txtGeneric.setTextColor(Color.BLUE);*/
        }
        table.addView(tr);
    }
}

Solution 6

You can use an inflater with TableRow:

for (int i = 0; i < months; i++) {
    
    View view = getLayoutInflater ().inflate (R.layout.list_month_data, null, false);
        
    TextView textView = view.findViewById (R.id.title);
    
    textView.setText ("Text");
        
    tableLayout.addView (view);
    
}

Layout:

<TableRow
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_centerInParent="true"
    android:gravity="center_horizontal"
    android:paddingTop="15dp"
    android:paddingRight="15dp"
    android:paddingLeft="15dp"
    android:paddingBottom="10dp"
    >
    
    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:gravity="center"
        />
    
</TableRow>

Solution 7

public Boolean addArtist(String artistName){

        SQLiteDatabase db= getWritableDatabase();

        ContentValues data=new ContentValues();
        data.put(ArtistMaster.ArtistDetails.COLUMN_ARTIST_NAME,artistName);
        long id = db.insert(ArtistMaster.ArtistDetails.TABLE_NAME,null,data);

        if(id>0){
            return true;
        }else{
            return false;
        }
    }

Solution 8

I am trying the above code with modification as per my requirement. The table is created properly. Bu the problem is when I am opening the activity 1st time, the table is not displaying. It is displaying 2nd time only.

My code is

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getSupportActionBar().hide();
        setContentView(R.layout.activity_aggre_ascendingorder);
        drawerLayout = findViewById(R.id.drawer_layout);
        init();
    }

    @SuppressLint("ResourceType")
    public void init() {
        stk = (TableLayout) findViewById(R.id.table_main);
        TableRow tbrow0 = new TableRow(this);
        TextView tv0 = new TextView(this);
        tv0.setText("Actual Values ");
        tv0.setWidth(330);
        tv0.setGravity(Gravity.CENTER);
        tv0.setTextColor(Color.WHITE);
        tv0.setTextSize(12);
        tv0.setBackgroundResource(R.drawable.border4);
        tbrow0.addView(tv0);
        TextView tv1 = new TextView(this);
        tv1.setText("Meter Values ");
        tv1.setWidth(330);
        tv1.setGravity(Gravity.CENTER);
        tv1.setTextColor(Color.WHITE);
        tv1.setTextSize(12);
        tv1.setBackgroundResource(R.drawable.border4);
        tbrow0.addView(tv1);
        TextView tv2 = new TextView(this);
        tv2.setText("Error ");
        tv2.setWidth(315);
        tv2.setGravity(Gravity.CENTER);
        tv2.setTextColor(Color.WHITE);
        tv2.setTextSize(12);
        tv2.setBackgroundResource(R.drawable.border4);
        tbrow0.addView(tv2);

        Intent z = getIntent();
        input1 = z.getIntExtra(EDIT, 1);
        input2 = z.getIntExtra(TEXT, 1);

        if (input2 == 0) {
            x = 400;
        } else {
            x = input1 / input2;
        }

        stk.addView(tbrow0);
        try {
            for (int i = 0; i < x + 1; i++) {
                TableRow tbrow = new TableRow(this);
                final EditText t1v = new EditText(this);
                t1v.setId(1);
                if (input2 == 0) {
                    t1v.setHint("");
                } else {
                    t1v.setText("" + i * input2);
                }
                final EditText t2v;
                TextView t3v = null;
                t1v.setTextColor(Color.BLACK);
                t1v.setGravity(Gravity.CENTER);
                t1v.setTextSize(12);
                t1v.setInputType(InputType.TYPE_CLASS_NUMBER);
                t1v.setBackgroundResource(R.drawable.border);


                t2v = new EditText(this);
                t2v.setHint("");
                t2v.setTextColor(Color.BLACK);
                t2v.setGravity(Gravity.CENTER);
                t2v.setTextSize(12);
                t2v.setInputType(InputType.TYPE_CLASS_NUMBER);
                t2v.setBackgroundResource(R.drawable.border);


                t3v = new TextView(this);
                t3v.setHint("");
                t3v.setTextColor(Color.BLACK);
                t3v.setGravity(Gravity.CENTER);
                t3v.setTextSize(12);
                t3v.setBackgroundResource(R.drawable.border);

                String stb = "0,0,0";

                if((Integer.parseInt(Prefs.getString("aggasstabLength",""))-1) > i){
                    stb = Prefs.getString("aggasstabVal_" + (i + 1), "");
                }
                //t1v.setText(stb.split(",")[0]);
                t2v.setText(stb.split(",")[1]);
                t3v.setText(stb.split(",")[2]);
                tbrow.addView(t1v);
                tbrow.addView(t2v);
                tbrow.addView(t3v);
                stk.addView(tbrow);
`

Can you clear me what is the mistake I am doing on this