Creating numerous LIstViews or TableLayouts programatically

66 views Asked by At

I have read various posts on programmatically creating a TableLayout/ListView and I'm still unsure of the best route to take.

In my mind I have one class called RunTests.java. One test schedule can contain numerous test types, and for each test type a table of results is required. So let's say there are four tests, named A, B, C and D.

After test A has completed I'd ideally like to call another class (ProcessTable.java) and pass it an array of test results, and array of test column headings and an array of test row headings. The class would then return a table, complete with results and headings, and inflate it so it becomes visible within an XML LinearLayout, and then move on to test B.

The process would then repeat and the next table would appear below the first one, and so on.

Any advice or examples would be great.

Thanks

Attempt at suggested answer:

I'm getting an error on listView, I'm not sure where I define this. The XML I've added to be existing layout is below:

private void createTable() {

        String[] columns = {"row_header", "column_name1", "column_name2"};
        String[] results = {"","2000","98"};
        int[] to = { R.id.row_header, R.id.txt1 ,R.id.txt2};
        String[] rowHeadings = {"","Bandwidth","QoS"};

        List<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();
        for(int i = 0; i < rowHeadings.length; i++){
            HashMap<String, String> map = new HashMap<String, String>();
            map.put(columns[0], rowHeadings[i].toString());
            map.put(columns[1], results[1]);
            map.put(columns[2], results[2]);
            data .add(map);
        }

         SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), data, R.layout.runtests, columns, to);         
         listView.setAdapter(adapter);
    }

XML:

 <LinearLayout android:id="@+id/resultsLayout"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="center|top"
         android:layout_marginEnd="8dp"
         android:layout_marginLeft="8dp"
         android:layout_marginRight="8dp"
         android:layout_marginStart="8dp"
         android:background="@drawable/curvedbg"
         android:layout_marginTop="10dp"
         android:padding="5dp"
         android:weightSum="99">

    <TextView android:id="@+id/row_header" android:layout_weight="33" />
    <TextView android:id="@+id/txt1" android:layout_weight="33"/>
    <TextView android:id="@+id/txt2" android:layout_weight="33"/>

</LinearLayout>
1

There are 1 answers

4
Ifrit On

My gut tells me you should be using a ListView. This will cater well to generating Views on the fly for varying data types. Also, if you have a rather large list of results that can't fit onto the screen, The ListView will auto handle scrolling and will only maintain in memory the data that displays to the screen.

On the other hand you'll need to wrap the TableLayout with a ScrollView and it will maintain all Views generated in memory...whether or not they are shown on the screen. You'll also need to setup a lot of boiler plate code just to get Views generated and attached to the main XML. In short, TableLayout would be great for static data.

Going with the ListView approach, it sounds like you should be using a SimpleAdapter. Not to terribly common as they are only useful for certain situations. Honestly the name should be ListMapAdapter as that's how it stores and expects data to be passed to it...via a List of Maps and it can be more difficult to use then an ArrayAdapter because it has one of the most confusing constructors ever. Basically the SimpleAdapter is great for rendering table like layouts, where you have columns of data.

Here's a basic example to give you an idea of how to use. This works for displaying Strings of data directly to a TextView.

//Columns is used to assign a column to a TextView.  So columns[1] will place all data 
//found in column 1 into to[1]...which is the TextView R.id.txt1. Columns is also used
//to map which data item belongs to a particular column
String[] columns = {"row_header", "column_name1", "column_name2", "column_name3"}
int[] to = { R.id.row_header, R.id.txt1 ,R.id.txt2, R.id.txt3};

//This is where you will assemble the test data. Probably the most difficult part 
//as you must convert your test results into a List of Maps.  Each index in the 
//List represents a row of data. The Map represents all the columns of data for 
//that row.
List<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();
for(int i = 0; i < rowHeadings.size(); i++){
    HashMap<String, String> map = new HashMap<String, String>();
    map.put(columns[0], rowHeadings.get(i));
    map.put(columns[1], Your_data_for_column1);
    map.put(columns[2], Your_data_for_column2);
    map.put(columns[3], Your_data_for_column3);
    data .add(map);
}

 SimpleAdapter adapter = new SimpleAdapter(getContext(), data, R.layout.list_layout, columns, to);         
 listView.setAdapter(adapter);

Higher Overview Example of list_layout.xml

<LinearLayout>
    <TextView android:id="@+id/row_header"/>
    <TextView android:id="@+id/txt1"/>
    <TextView android:id="@+id/txt2"/>
    <TextView android:id="@+id/txt3"/>
</LinearLayout>

Note whether or not the SimpleAdapter works for your data is more detail dependent. Using an ArrayAdapter, CursorAdapter, etc is just as viable. It all boils down to how your data is organized. Also, if you need to display your data in a more complex way then just Strings...you may need to override the adapters' getView()...and if thats the case, definitely be sure to use the adapter whose data organization best matches yours.