I have created tabs and their content from a database. Now I need help figuring out how to get the user entered values from those controls - how to get a list of the controls on the tabs (so the data can be saved). Here is a condensed sample of how I'm populating the tabs contents:
public View createTabContent(String tag)
{
SQLiteDatabase db2 = openOrCreateDatabase(msDbFile, MODE_PRIVATE, null);
Cursor cList = db2.rawQuery("SELECT * FROM CheckList WHERE CatID=" + tag, null);
TableLayout tl = new TableLayout(FormChecklist.this);
tl.setBackgroundColor(new Color().WHITE);
while(cList.moveToNext())
{
/* Create a new row to be added. */
TableRow tr = new TableRow(FormChecklist.this);
tr.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
/* Create the row-content. */
TextView lblQuestion = new TextView(FormChecklist.this);
lblQuestion.setText(cList.getString(2));
lblQuestion.setTag(tag);
/* Add control to row. */
tr.addView(lblQuestion);
CheckBox chkCompleted = new CheckBox(FormChecklist.this);
chkCompleted.setText("Completed");
chkCompleted.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
chkCompleted.setTag(tag);
/* Add control to row. */
tr.addView(chkCompleted);
/* Add row to TableLayout. */
tl.addView(tr,new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
db2.close();
return tl;
}
No replies, but finally figured out, hopefully someone will find this info helpful.
Approach I took was modifying my createTabContent adding an ID for the TableLayout:
tl.setId(1000 + miTlCnt);
Then in my save routine I loop through controls like so:
for (int i = 1000 + miTlCnt; i > 1000; i--)
{
TableLayout tl = (TableLayout)findViewById(i);
if (tl != null)
{
for (int j = 0; j < tl.getChildCount(); j++)
{
TableRow row = (TableRow)tl.getChildAt(j);
CheckBox chkCompleted = (CheckBox)row.getChildAt(1);
}
}
}
Related
I have created a table dynamically from an array list
for (int i = 0; i < arrayList.size(); i++) {
TextView name = new TextView(this);
TextView time = new TextView(this);
TableRow row = new TableRow(this);
// Set event name and remaining time
name.setText(arrayList.get(i).name);
time.setText("...");
// Add text views to row
row.addView(time, layoutParams);
row.addView(name, layoutParams);
// Add row to table
tableLayout.addView(row, i);
}
Now if I want to edit or remove certain rows under a condition, I will have to access that row, but how?
outerloop:
for(int i = 0; i < arrayList.size(); i++ ) {
if(// row's time <= 0 ...) {
tableLayout.removeViewAt(i); // this doesn't seem to work properly
// it removes the wrong rows
}
else {
// ...
break outerloop;
}
}
For some reason tableLayout.removeViewAt(i); removes the incorrect row. Alternatively, I'd prefer to edit that row's name, but the principle applies, I just need to find a way to access the table row. Any way?
Create your table like this:
ArrayList<TableRow> rows = new ArrayList<>();
for (int i = 0; i < arrayList.size(); i++) {
TextView name = new TextView(this);
TextView time = new TextView(this);
TableRow row = new TableRow(this);
rows.add(row);
// Set event name and remaining time
name.setText(arrayList.get(i).name);
time.setText("...");
// Add text views to row
row.addView(time, layoutParams);
row.addView(name, layoutParams);
// Add row to table
tableLayout.addView(row, i);
}
When you want to remove a row now you can do that by it's index in the ArrayList:
row = rows.get(i);
table.removeView(row);
rows.remove(i);
When you want to remove multiple rows this could be a solution for you:
ArrayList<TableRow> removeRows = new ArrayList<>();
for(int i = 0; i < rows.size(); i++) {
if(....) {
removeRows.add(rows.get(i));
}
}
// now delete those rows
for(TableRow remove : removeRows) {
tableLayout.removeView(row);
rows.remove(remove);
}
I hope this works for you!
I'm fairly new to Android programming and have completed my first app except for one issue on passing data from a table row that is selected (onClick). I've researched out here and tried most of the recommendations but I'm obviously missing something critical. I am a little confused on the getTag/Id and setTag/Id so maybe that's where I'm going wrong.
A little background, the table can have 1 to N number of rows populated dynamically from database, each row being clickable. Once a row is clicked, I need to pass the unique data of that row to the next activity (using Bundle for that which works fine). What doesn't work is that no matter which row I click, I only get the last row's data passed to the next activity and not the data of the clicked row.
Here's some of my pertinent code for the data add to row/table and onclick... What am I doing wrong to only get the last row's data? Really appreciate anyone's help in pointing me in the right direction.
public void addData(ArrayList<Auctions> auctions) {
prevCity = "";
currCity = "";
prevDate = "";
currDate = "";
prevTime = "";
currTime = "";
prevUnit = "";
currUnit = "";
for (Iterator i = auctions.iterator(); i.hasNext();) {
Auctions p = (Auctions) i.next();
if (p.getCity().equals(prevCity) && p.getDate().equals(prevDate) && p.getTime().equals(prevTime) && p.getSunit().equals(prevUnit)) {
//skip to next unique record
} else {
/** Create a City TableRow dynamically **/
row2 = new TableRow(this);
row2.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
/** Creating a TextView to add to the row **/
tvcity = new TextView(this);
currCity = p.getCity();
if (currCity.toString().equals(prevCity)) {
tvcity.setText("");
} else {
//create a blank row to separate from previous city entries
row1 = new TableRow(this);
row1.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
tvdummy = new TextView(this);
tvdummy.setText("");
tvdummy.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
row1.addView(tvdummy);
auctions_table.addView(row1, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
// work on the new city data
tvcity.setText(p.getCity());
}
tvcity.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
tvcity.setTextColor(getResources().getColor(R.color.red));
//add TextView data to row
row2.addView(tvcity);
// Add the TableRow to the TableLayout
auctions_table.addView(row2, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
// Create date, time, and unit name row dynamically
row3 = new TableRow(this);
row3.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
// Create TextViews to add to the Row -- Date and Time
tvdate = new TextView(this);
tvtime = new TextView(this);
tvsunit = new TextView(this);
currDate = p.getDate();
currTime = p.getTime();
currUnit = p.getSunit();
if ((currDate.toString().equals(prevDate)) && (currTime.toString().equals(prevTime))) {
tvdate.setText("");
tvtime.setText("");
} else {
tvdate.setText(p.getDate());
tvtime.setText(p.getTime());
}
if (currUnit.toString().equals(prevUnit)) {
tvsunit.setText("");
} else {
tvsunit.setText("Dynamic UNIT");
tvsunit.setText(p.getSunit());
}
tvdate.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT));
tvdate.setTextColor(getResources().getColor(R.color.blue));
tvtime.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT));
tvtime.setTextColor(getResources().getColor(R.color.blue));
tvsunit.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT));
tvsunit.setTextColor(getResources().getColor(R.color.blue));
//add TextView data to row
row3.addView(tvdate);
row3.addView(tvtime);
row3.addView(tvsunit);
row3.setId(t);
row3.setFocusable(false);
//row3.setClickable(true);
row3.setOnClickListener(new View.OnClickListener() {
//public OnClickListener tablerowOnClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
// Get the selected row's data
//row3.getId();
Bundle basket2 = new Bundle();
basket2.putString("ustate", state.getText().toString());
basket2.putString("abbrev", abbrev);
basket2.putString("ucity", currCity);
basket2.putString("uname", currUnit);
basket2.putString("auctiondate", currDate);
basket2.putString("auctiontime", currTime);
Intent StAuctions = new Intent(getApplicationContext(), StorageAuctionDetails.class);
StAuctions.putExtras(basket2);
StAuctions.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(StAuctions);
// Closing screen
//finish();
}
});
row3.setBackgroundResource(drawable.list_selector_background);
// Add the TableRow to the TableLayout
auctions_table.addView(row3, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
prevCity = currCity;
prevDate = currDate;
prevTime = currTime;
prevUnit = currUnit;
t++;
}
};
You are going to get these variables based on what they are when onClick is activated:
basket2.putString("ustate", state.getText().toString());
basket2.putString("abbrev", abbrev);
basket2.putString("ucity", currCity);
basket2.putString("uname", currUnit);
basket2.putString("auctiondate", currDate);
basket2.putString("auctiontime", currTime);
Those valued will be for whatever the last time you ran through your iteration.
You need to create a new "basket" for each row entry. Not in the click listener, but in the iteration loop, and make that basket the tag for that row, with something like this:
row3.setTag(basket2);
Can't decrypt your code sufficiently enough. But what I would suggest is that in your onClick(), put in Log.v("Row id is: ", Integer.toString(v.getId())) and see in LogCat if every time you click, it returns the same value.
Also, if I'm writing similar features, I might want to perform the extraction of row information in the onClick(), so information gets extracted from row and put into bundle on the fly, rather than passing the values into bundle during the iterator. Something like:
public void onClick(View v) {
String a; //extras for bundle
Bundle basket2 = new Bundle();
//iterate row's children and assign values to string here
for(int i = 0; i < v.getChildSize(); i++){
TextView t = (TextView)v.getChildAt(i);
//assignment
basket2.putString("someKey", a);
}
//send your intent
}
I need to add a number of rows to my Table layout and to each row I need to add two Image Buttons. Number of rows can be different each time I start the Activity - I look into a SQLite database and for each row in the database I need to add an Image Button. And there will be two Image Buttons in each row of Table layout. So far, I have this code:
db.open();
int count = db.getCount();
boolean newRow = true;
for (int i = 0; i < count; i++) {
if (newRow == true) {
newRow = false;
row = new TableRow(this);
row.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
ImageButton button = new ImageButton(this);
row.addView(button);
tableLayout.addView(row);
}
db.close();
TableRow row is defined above this block of code simply as variable for this Activity. My Table layout (tableLayout in code) is defined in XML code of the Activity layout:
<TableLayout
android:id="#+id/tableLayoutContacts"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TableLayout>
The code crashes at the line
tableLayout.addView(row);
I wasnt able to resolve this. Any ideas? Thanks!!
I think the problem is different
It seems that Your code will have only one row and you are adding that row again and again to tableLayout as shown below.
tableLayout.addView(row);
This will lead to IllegalStateException at addViewInner Function of ViewGroup
try this
db.open();
int count = db.getCount();
boolean newRow = false;
for (int i = 0; i < count; i++) {
if (i % 2 == 0)
newRow = true;
if (newRow == true) {
newRow = false;
row = new TableRow(this);
row.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
tableLayout.addView(row);
}
ImageButton button = new ImageButton(this);
row.addView(button);
}
db.close();
I'm still new in android programming, what I'm trying to do is, I want to create 5x5 dimension TableLayout. I know this can be done by using GridView BaseAdapter suing Inflate service. But for this one i try to apply using table layout. Below is the code. I create new instance of TableLayout, and new instance of Table row. On each table row, I created instance of 5 TextView. But once I open in emulator or in my phone, there is no TableRow created, it just empty blank Table Layout. Also there is no exception was thrown.
GridView navIcon = (GridView) findViewById(R.id.content);
navIcon.setAdapter(new ImageAdapter(this));
navIcon.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View v, int position,long id) {
// TODO Auto-generated method stub
if (position==0){
try{
TableLayout calgrid = (TableLayout) findViewById(R.id.gridtable);
Context ctxt = v.getContext();
TextView[] tView = new TextView[25];
calgrid = new TableLayout(ctxt);
int dip = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,(float) 1, getResources().getDisplayMetrics());
int counter=1;
TableRow[] tr = new TableRow[5];
for(int j=0;j<5;j++){
tr[j] = new TableRow(ctxt);
for(int i=0;i<5;i++){
tView[i] = new TextView(ctxt);
tView[i].setText(String.valueOf(counter));
tView[i].setTextSize(15);
counter+=1;
tView[i].setWidth(50 * dip);
tView[i].setPadding(20*dip, 0, 0, 0);
tView[i].setTextColor(Color.rgb( 100, 200, 200));
Toast.makeText(getApplicationContext(), "tView["+i+"] value " + String.valueOf(tView[i].getText()), Toast.LENGTH_SHORT).show();
tr[j].addView(tView[i], 50, 50);
}
calgrid.addView(tr[j]);
}
}catch(Exception e){
Log.e("MainActivity", "Error in activity", e);
Toast.makeText(getApplicationContext(),e.getClass().getName() + " " + e.getMessage(),Toast.LENGTH_LONG).show();
}
}
}
});
First of all, it is a mistake to do calgrid = (TableLayout) findViewById(R.id.gridtable); and then calgrid = new TableLayout(ctxt);, which basically says find this view now assign this variable to something completely different. Remove the second statement and it will load the table from xml which is what you want.
Second, I think it would be a good idea to simplify things for yourself because there is a lot going on here. Instead of doing all this work inside an onClick listener, do it in the onCreate method itself. Also, you seem to be using the Context from the GridView, which seems odd. Perhaps if you posted your xml layout file it could help explain what you are trying to do?
There is also a problem with indices in the array of TextViews, as tView[i] will only assign items up to 5 but the array contains 25 items. Try using tView[(j*5)+i] instead. I don't think this is causing your problems but just make sure you are assigning your items correctly.
Here is an example of how to do something along the lines of what you want
setContentView(R.layout.grid);
TableLayout tl = (TableLayout) findViewById(R.id.gridtable);
for (int j = 0; j < 5; j++) {
TableRow tr = new TableRow(this);
tr.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
for (int i = 0; i < 5; i++) {
TextView tView = new TextView(this);
tView.setText("TEXT" + String.valueOf((j * 5) + i + 1));
tView.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
tr.addView(tView);
}
tl.addView(tr, new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
and grid.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridtable"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</TableLayout>
Once you get it working in the activity itself you can try to put it inside a listener attached to a GridView. Hope this helps!
I am trying to extend the TableLayout class, such that rows will be populated automatically by the class. The issue I am having is the rows that I add inside the custom class do not display.
Ex. within the Activity:
private TextView getTableCell(String text) {
TextView tv = new TextView(this);
tv.setText(text);
tv.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
return tv;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DatasetTableLayout table = (DatasetTableLayout) findViewById(R.id.table);
TableRow tr = new TableRow(this);
tr.addView(getTableCell("activity1"));
tr.addView(getTableCell("activity2"));
tr.addView(getTableCell("activity3"));
table.addView(tr);
This successfully adds a row to the table. However, within my custom class:
private TextView getTableCell(String text) {
TextView tv = new TextView(context);
tv.setText(text);
tv.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
return tv;
}
private void update() {
TableRow tr = new TableRow(context);
tr.addView(getTableCell("class1"));
tr.addView(getTableCell("class2"));
tr.addView(getTableCell("class3"));
addView(tr);
}
does not successfully add a row. Well, it does add a row, as getChildCount(), and getChildAt() do return this row - but it does not get displayed.
Am I missing something?
#theresia (Can't seem to format text if I add a comment):
It does appear that it adds the TableRow:
for(int i = 0; i < getChildCount(); i++) {
TableRow row = (TableRow) getChildAt(i);
for(int j = 0; j < row.getChildCount(); j++) {
TextView tv = (TextView) row.getChildAt(j);
Log.e("DatasetTableLayout-data", tv.getText().toString() + " ");
}
}
gives me:
01-24 11:03:31.668: ERROR/DatasetTableLayout-data(1624): activity1
01-24 11:03:31.677: ERROR/DatasetTableLayout-data(1624): activity2
01-24 11:03:31.698: ERROR/DatasetTableLayout-data(1624): activity3
01-24 11:03:31.698: ERROR/DatasetTableLayout-data(1624): class1
01-24 11:03:31.698: ERROR/DatasetTableLayout-data(1624): class2
01-24 11:03:31.727: ERROR/DatasetTableLayout-data(1624): class3
My guess would be something along this line: addView(tr); Does it successfully add your TableRow to TableLayout?
Edit:
TableLayout tb = new TableLayout(this);
TableRow tr = new TableRow(this);
TextView tv = new TextView(this);
tv.setText("row");
tr.addView(tv);
tb.addView(tr); // this is what I mean
setContentView(tb);
Your code for creating rows works fine, but if you haven't add it to the table, and later on, add the table to the parent view as well, your rows wouldn't get displayed.