I have an XML layout which contains a TableLayout with an unknown number of TableRows...
The number of Rows will be established durin runtime, what I do know though is that I want two columns...
So I have a couple of questions regarding this :
- is there a way to set the whole TableLayout to have 2 columns ?
- is there a way programmatically to give an id to the (during runtime) created TableRows which will be placed within the TableLayout, so I can reference them later on from other parts of the software ?
You can build your table rows via XML parts and LayoutInflater. Say you had this as your table_cell.xml:
<TextView android:id="#+id/text"
android:text="woot" />
And this as your table_row.xml (unless you're doing something fancy with your TableRow, you may not need to put it in it's own XML file, and instead just create it programmatically. The result will be the same):
<TableRow />
Assuming your TableLayout reference was called "table", you could do something like this:
TableLayout table = (TableLayout)findViewById(R.id.table);
LayoutInflater inflater = getLayoutInflater();
for(int i = 0; i < 5; i++) {
TableRow row = (TableRow)inflater.inflate(R.layout.table_row, table, false);
View v = (View)inflater.inflate(R.layout.table_cell, row, false);
row.addView(v);
v = (View)inflater.inflate(R.layout.table_cell, row, false);
row.addView(v);
// you can store your reference to `row` here for later use
table.addView(row);
}
With this technique, you can still set up your layout in XML, making it easier to read/organize/edit, and you still have programmatic control over how many columns and rows are in the table. You can also store references to each table row for later use.
Related
In an Android app, I am trying to dynamically populate a TableLayout from an array, and I want each TableRow to hold at maximum 3 elements.
The way I had to implement it (code below), feels a lot like dynamically creating HTML tables and I was wondering if Android had more ad-hoc layout facilities that don't make me feel as if I am forcing my design idea over a more generic Layout like TableLayout.
Ideally, I would just like to deal with a layout that:
is aware of the number of elements I want per row (maybe via configuration?),
automatically stacks the TextViews horizontally, wrapping them on the next row only if they fill up the previous, so that I could simply cycle through the array elements and do myLayout.add(TextView).
Do we have something like that, or there's no other better way than handcrafting it?
In the latter case, how would you've done that?
TableLayout tab_lay = (TableLayout) viewRef.findViewById(R.id.myTableLayout);
TableRow table_row = new TableRow(contextRef);
int col_counter = 0;
for (TextView aTextView : arrayOfTextViews) {
table_row.addView(aTextView);
col_counter++;
if (col_counter == 3) {
tab_lay.addView(table_row);
table_row = new TableRow(contextRef);
col_counter = 0;
}
}
I'm developing my first app and I want to show a grid in which there is a list of entries. I get those entries through queries on local SQLite database so this it is a dynamic list. Every item of this list should have 2 field: a string and a value.
How to correctly do it in an activity?
I see ListView but it doesn't seem to suit my needs and I do not need clickable items.
Can you suggest a better solution?
I would still use a ListView.
They don't have to be clickable, you can customise the view to have 2 columns (or to be whatever you want) and they have great performance benefits with view recycling, etc during scrolling.
Essentially you need to return a custom view as the row - this row view will have data aligned horizontally and so you can get columns.
Here is an example.
Create programatically or in XML LinearLayout with vertical orientation:
LinearLayout layout = findViewById(r.id.layout);
layout.setOrientation(LinearLayout.VERTICAL);
Then create Textview for every item with text consisting of string and value of item and add them to the layout:
for (int i=0; i<items.size; i++) {
TextView tv = new TextView(context);
tv.setText(items[i].stringName + ": " + items[i].value);
layout.addView(tv);
}
I have two layout files, a main one containing a custom view, and a table, and a row layout.
Depending on circumstances, the table needs additional rows, inflated from the row layout like this:
TableLayout tl = (TableLayout) mParent.findViewById(R.id.table_layout);
LayoutInflater inflater = LayoutInflater.from(mParent);
TableRow tr = (TableRow) inflater.inflate(R.layout.layout_row, null);
tl.addView(tr, 0);
This works as intended.
tl.addView(tr)
This does nothing at all.
Why? I spent half an hour on this, before I tried the addView with two arguments, and I can now make this work, yet it would be better to actually understand why.
Thanks!
Stupid question. It was added, but invisible because out of the screen. Sorry about this.
I'm adding rows to my TableLayout dynamically and each row has more than one TextView.
I want to loop for each row in my TableLayout and I want to update some rows (not every row), for example the text of TextView in my rows. How can I manage this?
Loop through the children of the TableLayout, they should be TableRows (or another layout) - skip the ones you don't want to update. Loop through or findViewById the children of the TableRow (or whatever) which will be your TextViews
When you add the TextView / CheckBox to the TableRow, you can set the View's id with setId(R.id.id_of_the_view) (which you might want to add to the res/values/ids.xml file).
Then loop through like so:
TableLayout tableLayout = null;
for(int n = 0, s = tableLayout.getChildCount(); n < s; ++n) {
TableRow row = (TableRow)tableLayout.getChildAt(n);
TextView name = (TextView)row.findViewById(R.id.tv_name);
}
since you're using row.findViewById, you're looking for a specific id inside a specific row.
I recommend using the setTag method to quick reach specific rows, and Views within rows.
For example, lets say you have a CheckBox in a certain column, which represents "isSomethingEnabled". When creating the CheckBox, do setTag("foo").
Use setTag on the row as well, such as setTag("rowKey")
To quickly get to a specific row
TableRow tRow = (TableRow) tLayout.findViewWithTag("rowKey");
And to quickly get to a specific child
View v = tRow.findViewWithTag("foo");
I'm trying to create a TableLayout with dynamically added rows and columns (from an array of obbjects). Since it's dynamic must I code(?)
All the examples I can find is doing it using xml layouts. The only ones out there that does it in code only adds a single view, like a button, which makes me believe its not doable, and I need two columns at least, where one of the will contain a view with an image and text.
Try to create table and row doing something like this
TableLayout t=new TableLayout(this);
TableRow tr=new TableRow(this);
and add row with table by
t.addView(tr);
similarly you can add other view (text, image view etc.) by using addView() function