Adding a dynamic TableLayout with borders in a Android App
Asked Answered
B

2

7

I am creating a Android app. This Android App will have objects that are dynamic. These objects are Places with a Address or Lat/Long, and distance from current location, and a ETA. What I would like to do is add with objects on a TableLayout with borders, but I need to be able to dynamically add rows as the number of places increase.

I understand somewhat how to do this for a fixed hardcoded number of items on the xml, but what would be the best way when the number of objects is coming from the Activity.java file?

Below is a screenshot of the TableLayout I would like:

Table Layout

So the object would be a place with a address, distance and direction.

Bosch answered 15/3, 2013 at 22:58 Comment(0)
V
8

but I need to be able to dynamically add rows as the number of places increase.

This isn't difficult, when you have a new object append a TableRow with the data to the TableLayout.

I understand somewhat how to do this for a fixed hardcoded number of items on the xml, but what would be the best way when the number of objects is coming from the Activity.java file?

I don't think there is a best way (or what you consider best way). You either:

  • Insert fake views to act as dividers. This would be easier to implement visually but it will also increase the memory consumption of your app, with bad consequences if the number of rows is big. (1)
  • Or use drawables for the backgrounds to simulate the borders (like nine-patch images). This would be simpler then inserting additional views but you need a bit more talent to make it look well. (2)

Some examples for your image:

(1)

private static final int DIVIDER_SIZE = 2;

// rowsCount the number of rows to add to the TableLayout
private void buildOldSchool(TableLayout table, int rowsCount) {
    View divider;
    for (int i = 0; i < rowsCount; i++) {
        TableRow row = new TableRow(this);
        for (int j = 0; j < 7; j++) {
            if (j % 2 == 0) {
                divider = new View(this);
                divider.setLayoutParams(new TableLayout.LayoutParams(
                        DIVIDER_SIZE, TableLayout.LayoutParams.MATCH_PARENT));
                divider.setBackgroundColor(Color.GREEN);
                row.addView(divider, new TableRow.LayoutParams(
                        DIVIDER_SIZE, TableRow.LayoutParams.MATCH_PARENT));
                continue;
            }
            TextView tv = new TextView(this);
            tv.setText("DX"); // dummy data
            row.addView(tv, new TableRow.LayoutParams(
                    TableRow.LayoutParams.MATCH_PARENT,
                    TableRow.LayoutParams.WRAP_CONTENT));
        }
        divider = new View(this);
        divider.setLayoutParams(new TableLayout.LayoutParams(
                TableLayout.LayoutParams.MATCH_PARENT, DIVIDER_SIZE));
        divider.setBackgroundColor(Color.GREEN);
        if (i == 0) {
            table.addView(divider);
            divider = new View(this);
            divider.setLayoutParams(new TableLayout.LayoutParams(
                    TableLayout.LayoutParams.MATCH_PARENT, DIVIDER_SIZE));
            divider.setBackgroundColor(Color.GREEN);
        }
        table.addView(row);
        table.addView(divider);
    }
}

(2) or with images:

private void buildWithDrawables(TableLayout table, int rowsCount) {
    for (int i = 0; i < rowsCount; i++) {
        TableRow row = new TableRow(this);
        row.setBackgroundResource(i == 0 ? R.drawable.firstrow
                : R.drawable.normalrow);
        for (int j = 0; j < 3; j++) {
            TextView tv = new TextView(this);
            tv.setBackgroundResource(j == 2 ? R.drawable.extra
                    : R.drawable.cell);
            tv.setText("DX");
            row.addView(tv, new TableRow.LayoutParams(
                    TableRow.LayoutParams.MATCH_PARENT,
                    TableRow.LayoutParams.WRAP_CONTENT));
        }
        table.addView(row);
    }
}

Where the images are:

  • R.drawable.cell:

  • R.drawable.extra (a visually transparent drawable which replicates the nine-patch above):

  • R.drawable.normalrow:

  • R.drawable.firstrow:

Ignore my design skills.

If your foresee a large number of rows I would advise you to use a ListView, which you could pretty easy make it to look like a table with borders.

Velites answered 18/3, 2013 at 20:51 Comment(1)
That's actually exactly what I decided on. I created a drawable xml to use.Bosch
Z
1

Couldn't figure out the vertical line, but something you can build upon

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

    ScrollView sv = new ScrollView(this);

    TableLayout ll=new TableLayout(this);
    HorizontalScrollView hsv = new HorizontalScrollView(this);

    for(int i=1;i<5;i++) {
        TableRow tbrow=new TableRow(this);

        for(int j=1;j<=3;j++) {
            TextView tv1=new TextView(this);
            tv1.setText("Element :"+ i + "" + j);
            tbrow.addView(tv1);                
        }
        ll.addView(tbrow);
        View v = new View(this);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 5);
        v.setLayoutParams(params);
        v.setBackgroundColor(getResources().getColor(android.R.color.white));
        ll.addView(v);
    }
    hsv.addView(ll);
    sv.addView(hsv);
    setContentView(sv);
}
Zwick answered 18/3, 2013 at 16:26 Comment(1)
This somewhat works but I have a list of objects that I want to iterate through.Bosch

© 2022 - 2024 — McMap. All rights reserved.