Android table layout - android

In my app i'am setting each table row in code.
Row setting code
final TableRow row = new TableRow(context);
row.setBackgroundResource(R.drawable.layer_nw);
row.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, 150));
row.setMinimumHeight(100);
//tr.addView(view);
String[] colText = {"" + outlet_name, "" + outlet_qty, "" + outlet_price, "" + outlet_tot};
for (String text : colText) {
TextView tv = new TextView(this);
//EditText ev=new EditText(this);
tv.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,150));
tv.setGravity(Gravity.CENTER);
tv.setTextSize(14);
// tv.setTextColor(Integer.parseInt("#D3D3D3"));
tv.setText(text);
row.addView(tv);
}
tableLayout.addView(row);
in this row i want the second cell,that is 'outlet_qty' as edit text and all other as textview.each of the 'colText' array variables gets its value from Sqlite..
is there any way to achievethis?pls help

This all is to manage TextView and EditText for a specific column number. you can manage data input from sqlite as how you are doing as same.
final TableRow row = new TableRow(context);
row.setBackgroundResource(R.drawable.layer_nw);
row.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, 150));
row.setMinimumHeight(100);
//tr.addView(view);
String[] colText = {"" + outlet_name, "" + outlet_qty, "" + outlet_price, "" + outlet_tot};
for (int i = 0; i < colText.length; i++) {
EditText ev = new EditText(this);
TextView tv = new TextView(this);
if (i == 1) {//For outlet_qty
ev.setId(i);
ev.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, 150));
ev.setGravity(Gravity.CENTER);
ev.setTextSize(14);
// ev.setTextColor(Integer.parseInt("#D3D3D3"));
ev.setText(colText[i]);
ev.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() > 0) {
((TextView) row.findViewById(Integer.valueOf(3))).setText(s.toString().trim());
} else {
((TextView) row.findViewById(Integer.valueOf(3))).setText("");
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
row.addView(ev);
} else {
tv.setId(i);
tv.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, 150));
tv.setGravity(Gravity.CENTER);
tv.setTextSize(14);
// tv.setTextColor(Integer.parseInt("#D3D3D3"));
tv.setText(colText[i]);
row.addView(tv);
}
}
tableLayout.addView(row);

try this. In the for Loop where you iterate over the columns we check if the colum is outlet_qty. if we match the outlet_qty column we add a Edit text. And for all other we add the text views.
final TableRow row = new TableRow(context);
row.setBackgroundResource(R.drawable.layer_nw);
row.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, 150));
row.setMinimumHeight(100);
//tr.addView(view);
String[] colText = {"" + outlet_name, "" + outlet_qty, "" + outlet_price, "" + outlet_tot};
// iterate over colunms
for (String text : colText) {
// add edit text for outlet_qty column
if(text.equals(outlet_qty))
{
EditText editText = new EditText(this);
// do stuff with the edit text like prefilling data etc
row.addView(tv);
}
// for all others we add text views
else
{
TextView tv = new TextView(this);
//EditText ev=new EditText(this);
tv.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,150));
tv.setGravity(Gravity.CENTER);
tv.setTextSize(14);
// tv.setTextColor(Integer.parseInt("#D3D3D3"));
tv.setText(text);
row.addView(tv);
}
}
tableLayout.addView(row);

Related

How to fetch edittext and text values created dynamically?

Am trying to create edittext and textview widgets dynamically into program. it works fine. now i want to access the textvalue with its corresponding edittext value. how to do it?
Here is what i have tried.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_callreport);
dcname = ProductdetailsEnd.doctor;
resultArr1 = ProductdetailsEnd.resultArr;
callreportbtn = (Button) findViewById(R.id.callreportbtn);
arraysize = resultArr1.length;
TableLayout tb = (TableLayout) findViewById(R.id.tablelayout);
for (int i = 0; i < arraysize; i++) {
res = resultArr1[i];
TableRow tr = new TableRow(this);
TableRow.LayoutParams pl = new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT);
tr.setLayoutParams(pl);
tr.setWeightSum(1.0f);
product = new TextView(this);
product.setLayoutParams(new TableRow.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 0.7f));
product.setId(i);
qty = new EditText(this);
qty.setLayoutParams(new TableRow.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 0.3f));
qty.setId(i);
qty.setWidth(50);
product.setText(res);
tr.addView(product);
tr.addView(qty);
tb.addView(tr, i);
Log.d("Call Report name : ", "" + dcname);
Log.d("Call Report prod :", "" + res);
}
Log.d("res length : ", "" + arraysize);
for (int i = 0; i < arraysize; i++) {
String product1 = resultArr1[i];
String qty1 = qty.getText().toString();
Log.d("products &&: ", "" + product1 + ":" + qty1);
}
callreportbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "Hello",
Toast.LENGTH_LONG).show();
for (int i = 0; i < arraysize; i++) {
String product1 = resultArr1[i];
String qty1 = qty.getText().toString();
Log.d("products &&: ", "" + product1 + ":" + qty1);
}
}
});
}
after entering the value, when i say submit it should display the textview value along with edittext value.
For more convenience i have added a snap of my output.
first image to enter the value
second image is output in logcat.
There are many ways to do what you want.
Place your views inside a List object, and read the list when you submit.
Implement TextWatcher interface and record your String values as they change.
Assign an Id to your views, and later retrieve your views by Id.
Third option required you to carefully assign id's, because I think they must be unique. Second option, I think, is best one in many cases, since you may also want to provide some feedback to user.
EDIT:
TextWatcher is interface that receives callbacks from TextView. Simply call addTextChangedListener method and provide a TextWatcher implementation.
aTextView.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
Finally i got the answer. referred this post - Creation of EditText Dynamically and get their text from each of EditText
Created an array of the EditText and accessed it in the button onclick method.
this is my code and its working.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_callreport);
dcname = ProductdetailsEnd.doctor;
resultArr1 = ProductdetailsEnd.resultArr;
callreportbtn = (Button) findViewById(R.id.callreportbtn);
quantity = new ArrayList<EditText>();
arraysize = resultArr1.length;
TableLayout tb = (TableLayout) findViewById(R.id.tablelayout);
for (int i = 0; i < arraysize; i++) {
res = resultArr1[i];
TableRow tr = new TableRow(this);
TableRow.LayoutParams pl = new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT);
tr.setLayoutParams(pl);
tr.setWeightSum(1.0f);
product = new TextView(this);
product.setLayoutParams(new TableRow.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 0.7f));
product.setId(i);
qty = new EditText(this);
qty.setLayoutParams(new TableRow.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 0.3f));
//qty.setId(i);
qty.setWidth(50);
product.setText(res);
tr.addView(product);
tr.addView(qty);
tb.addView(tr, i);
quantity.add(qty);
Log.d("Call Report name : ", "" + dcname);
Log.d("Call Report prod :", "" + res);
}
Log.d("res length : ", "" + arraysize);
Log.d("qty length : ", "" + qty.length());
String[] items1 = new String[quantity.size()];
for (int i = 0; i < arraysize; i++) {
String product1 = resultArr1[i];
items1[i] = quantity.get(i).getText().toString();
Log.d("qty id ", "" +qty.toString());
Log.d("products &&: ", "" + product1 + ":" + items1);
}
callreportbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "Hello",
Toast.LENGTH_LONG).show();
String[] items = new String[quantity.size()];
for (int i = 0; i < arraysize; i++) {
String product1 = resultArr1[i];
items[i] = quantity.get(i).getText().toString();
Log.d("products &&: ", "" + product1 + ":" + items[i]);
}
}
});
}

Table get selected row index

I am having some problem when trying to get the value of the first column when the checkbox of certain row is checked using Android. Here is my codes:
private ArrayList<String> exerciseIDList = new ArrayList<String>();
private void BuildTable() {
try {
String sql = "SELECT * FROM exercise";
Cursor mCur = mDb.rawQuery(sql, null);
if (mCur.getCount() != 0) {
if (mCur.moveToFirst()) {
do {
int cols = mCur.getColumnCount();
TableRow row = new TableRow(this);
row.setLayoutParams(new LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
for (int j = 0; j < cols + 1; j++) {
if (j == cols) {
CheckBox cb = new CheckBox(this);
cb.setLayoutParams(new TableRow.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
cb.setGravity(Gravity.LEFT);
row.addView(cb);
final View rowIndex = table_layout.getChildAt(j);
cb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int rowID = table_layout.indexOfChild(rowIndex);
exerciseIDList.add(Integer.toString(rowID));
}
});
break;
}
TextView tv = new TextView(this);
tv.setLayoutParams(new TableRow.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
tv.setGravity(Gravity.LEFT);
tv.setTextSize(10);
tv.setText(mCur.getString(j));
row.addView(tv);
}
table_layout.addView(row);
} while (mCur.moveToNext());
}
}
} catch (SQLException mSQLException) {
throw mSQLException;
}
}
Basically I have 3 columns in my database, ID, exerciseType and amount. When I do a for loop, I +1 the cols to add checkbox to the end of each row. And when the checkbox is checked, I supposed to get the value of the first column which is ID and store into the list.
However, from the codes I provided above, it does not get the value of the first column of checked row. It is just simply looping start from 0.
Any guides?
The issue you are having is that you are referring to a non-final variable inside an anonymous class (View.OnClickListener()). See this post for more information. I would suggest the following:
final int k = mCur.getInt(mCur.getColumnIndex("id")); //I'm not sure what you named your ID column, but put that here
cb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
exerciseIDList.add(Integer.toString(k));
}
});
Basically, just create a new final variable k and assign it to your return from the Cursor.getInt(). That should get you through this error.

Make a paragraph using array of textview android

String[] textArray={"one","two","three", "four", "five", "six"};
int length=textArray.length;
TextView[] textViewArray = new TextView[length];
LinearLayout layout = (LinearLayout) findViewById(R.id.linear);
for(int i=0;i<length;i++){
textViewArray[i] = new TextView(this);
textViewArray[i].setText(textArray[i]);
layout.addView(textViewArray[i]);
}
I need to do something like that.. so it would display as
one two three four
five six
It is not fix that only four words to display in a line, only want fit to screen and look like a paragraph. Please provide me suggestions.
You can append the string to textview and append space for each string added as below. You don't need array of textviews. Just append the strings to the same.
TextView tv= new TextView(MainActivtiy.this);
tv.setText("");
for(int i=0;i<textArray.length;i++)
{
tv.append(textArray[i]);
tv.append(" ");
}
layout.addView(tv);
Edit:
TextView tv= new TextView(MainActivtiy.this);
tv.setText("");
for(int i=0;i<textArray.length;i++)
{
SpannableString ss1= new SpannableString(textArray[i]);
ss1.setSpan(new MyClickableSpan(textArray[i]), 0, ss1.length(),
tv.append(ss1);
tv.append(" ");
}
layout.addView(tv);
MyClickableSpan Class
class MyClickableSpan extends ClickableSpan{
String clicked;
public MyClickableSpan(String string) {
// TODO Auto-generated constructor stub
super();
clicked =string;
}
public void onClick(View tv) {
Toast.makeText(MainActivity.this,clicked ,Toast.LENGTH_SHORT).show();
//do what is required
}
public void updateDrawState(TextPaint ds) {
ds.setColor(Color.BLUE);//set text color
//ds.setStrokeWidth(15f);
ds.setUnderlineText(true); // set to false to remove underline
}
}
It can be achieved as follows
String text = "";
for(int i=0;i<length;i++){
text += text + " " + textArray[i];
}
tv = new TextView(this);
tv.setText(text);
tv.setSingleLine(false);
Declare a string object and keep appending array values to it and set value to textview once string is complete.
String para = "";
for(int i=0;i<length;i++){
para += textArray[i] + " ";
}
textViewArray[i] = new TextView(this);
textViewArray[i].setText(para);
layout.addView(textViewArray[i]);
You can do something like that
StringBuffer text = new StringBuffer();
for(int i=0;i<length;i++){
text.append(textArray[i]);
}
textViewArray = new TextView(this);
textViewArray.setText(text.toString().trim());
textViewArray.setSingleLine(false);
layout.addView(textViewArray);

get id/tag from dynamically generated seekbar

In my app the user chooses how many seekbars they need and then my code generates them (see below).
// dynamically creates the view objects
tL = (TableLayout)findViewById(R.id.tableLayout1);
// creates all the fields
for(int i = 1; i <= numOfStockTanks; i++) {
TableRow tR = new TableRow(this);
// creates the textView
tV1 = new TextView(this);
tV1.setText(" " + tankNum[i - 1] + ": ");
tV1.setPadding(2, 0, 0, 0);
// creates the seekBar
sBGauge = new SeekBar(this);
sBGauge.setMax(depthL - 1);
sBGauge.setMinimumWidth(150);
sBGauge.setId(2000 + 1);
sBGauge.setOnSeekBarChangeListener(this);
// shows the progress of the seekBar
tVGauge = new TextView(this);
tVGauge.setText("0-0.0\"");
tVGauge.setId(3000 + i);
// adds objects to row
tR.addView(tV1);
tR.addView(sBGauge);
tR.addView(tVGauge);
// add the TableRow to the TableLayout
tL.addView(tR, new TableLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
// creates new tableRow
TableRow tR2 = new TableRow(this);
// add's a "+" button to tableRow
buttonPlus = new Button (this);
buttonPlus.setWidth(60);
buttonPlus.setText("+");
buttonPlus.setId(4000 + i);
buttonPlus.setOnClickListener(new MyPOnClickListener());
// add's a "-" button to tableRow
buttonMinus = new Button (this);
buttonMinus.setWidth(60);
buttonMinus.setText("-");
buttonMinus.setId(5000 + i);
buttonMinus.setOnClickListener(new MyMOnClickListener());
// add TextView tVChange to show change from previous sqlite entry
tVChange = new TextView (this);
tVChange.setText("Change");
tVChange.setId(6000 + i);
// add the TextView and the buttons to the new TableRow
tR2.addView(buttonPlus);
tR2.addView(buttonMinus);
tR2.addView(tVChange);
// add the TableRow to the TableLayout
tL.addView(tR2,new TableLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
} // end for statement
my problem is when I use my onProgressChanged method:
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
int seekId = sBGauge.getId();
seekId = seekId - 2000;
try {
tVGauge = (TextView) findViewById(seekId + 3000);
} // end try
catch (Exception e) {Toast.makeText(this, "fail", Toast.LENGTH_LONG).show();}
try {
// sets the text of the textview
tVGauge.setText(depth.get(progress));
} // end try
catch (Exception e) {}
manualP = progress;
}
My problem is that all my seekBars only change the first progress bars textView, the buttons change the proper text view.
Thanks for your help
You are setting the same id to each seekbar
sBGauge.setId(2000 + 1);
change 1 to i
sBGauge.setId(2000 + i);

Getting java.util.concurrent.RejectedExecutionException from asyncTask on android

I am reading a sqlite database into a tableLayout. I wan't to do this in a seperate thread instead of having a long wait with no ui updates. So I used an AsyncTask to do some of the work and publish the results. However only about 1/4th of the item in my list actually make it on to the TableLayout. It works fine without the AsyncTask. Most of the items on the list throw an error (which I caught) java.util.concurrent.RejectedExecutionException. I'm not sure why this is. Here is my code.
myDB.execSQL("CREATE TABLE IF NOT EXISTS "
+ TableName
+ " (_id INTEGER PRIMARY KEY, filepath TEXT UNIQUE, title TEXT, artist TEXT, album TEXT, time TEXT, playcount NUMERIC);");
Cursor c = myDB.rawQuery("SELECT * FROM " + TableName, null);
c.moveToFirst();
if (c != null) {
int color = 0xFFdfe8ea;
this.startManagingCursor(c);
// Loop through all Results
do {
try{
MyAsyncTask aTask = new MyAsyncTask();
String[]strings= {c.getString(c.getColumnIndex("title")),c.getString(c.getColumnIndex("artist")),c.getString(c.getColumnIndex("time")),c.getString(c.getColumnIndex("album")),""+color};
aTask.execute(strings);
}catch(Exception e){
Log.w("****", e);
}
if (color == 0xFFdfe8ea) {
color = 0xFFf2f8fa;
} else {
color = 0xFFdfe8ea;
}
} while (c.moveToNext());
}
} catch (SQLException e) {
Log.e("****", e.toString());
} finally {
if (myDB != null) {
myDB.close();
}
}
and here is the AsyncTask
class MyAsyncTask extends AsyncTask<String, Void, View> {
#Override
protected View doInBackground(String... params) {
int color = Integer.parseInt(params[4]);
TableRow tr = new TableRow(MainActivity.this);
tr.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
TextView space = new TextView(MainActivity.this);
space.setText("");
space.setBackgroundColor(color); //0xFFf2f8fa alternating
space.setSingleLine();
space.setPadding(2, 2, 2, 2);
space.setGravity(Gravity.LEFT);
space.setTextColor(0xFF000000);
space.setLayoutParams(new LayoutParams(
findViewById(R.id.spaceColumn).getWidth(),
LayoutParams.WRAP_CONTENT));
/* Create a Button to be the row-content. */
TextView title = new TextView(MainActivity.this);
title.setText(params[0]);
title.setBackgroundColor(color); //0xFFf2f8fa alternating
title.setSingleLine();
title.setPadding(2, 2, 2, 2);
title.setGravity(Gravity.LEFT);
title.setTextColor(0xFF000000);
title.setEllipsize(TruncateAt.END);
title.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Create a Button to be the row-content. */
TextView artist = new TextView(MainActivity.this);
artist.setText(params[1]);
artist.setBackgroundColor(color); //0xFFf2f8fa alternating
artist.setSingleLine();
artist.setPadding(2, 2, 2, 2);
artist.setGravity(Gravity.LEFT);
artist.setTextColor(0xFF000000);
artist.setEllipsize(TruncateAt.END);
artist.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Create a Button to be the row-content. */
TextView time = new TextView(MainActivity.this);
time.setText(params[2]);
time.setBackgroundColor(color); //0xFFf2f8fa alternating
time.setSingleLine();
time.setPadding(2, 2, 2, 2);
time.setGravity(Gravity.LEFT);
time.setTextColor(0xFF000000);
time.setLayoutParams(new LayoutParams(
findViewById(R.id.timeColumn).getWidth(),
LayoutParams.WRAP_CONTENT));
/* Create a Button to be the row-content. */
TextView album = new TextView(MainActivity.this);
album.setText(params[3]);
album.setBackgroundColor(color); //0xFFf2f8fa alternating
album.setSingleLine();
album.setPadding(2, 2, 2, 2);
album.setGravity(Gravity.LEFT);
album.setTextColor(0xFF000000);
album.setEllipsize(TruncateAt.END);
album.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Add Button to row. */
tr.addView(space);
tr.addView(title);
tr.addView(artist);
tr.addView(time);
tr.addView(album);
/* Add row to TableLayout. */
return tr;
}
#Override
protected void onPostExecute(View tr) {
((TableLayout) findViewById(R.id.tableLayout)).addView(tr, new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
#Override
protected void onPreExecute() {
}
}
For reference this is how I fixed it.
class MyAsyncTask extends AsyncTask<Void, Song, Void> {
#Override
protected Void doInBackground(Void... params) {
SQLiteDatabase myDB = openOrCreateDatabase("DatabaseName", MODE_PRIVATE, null);
String TableName = "songs";
myDB.execSQL("CREATE TABLE IF NOT EXISTS "
+ TableName
+ " (_id INTEGER PRIMARY KEY, filepath TEXT UNIQUE, title TEXT, artist TEXT, album TEXT, time TEXT, playcount NUMERIC);");
Cursor c = myDB.rawQuery("SELECT * FROM " + TableName, null);
c.moveToFirst();
int filepathIndex=c.getColumnIndex("filepath");
int titleIndex=c.getColumnIndex("title");
int artistIndex=c.getColumnIndex("artist");
int albumIndex=c.getColumnIndex("album");
int timeIndex=c.getColumnIndex("time");
int playcountIndex=c.getColumnIndex("playcount");
if (c != null) {
int color = 0xFFdfe8ea;
// this.startManagingCursor(c);
// Loop through all Results
do {
Song song = new Song(c.getString(filepathIndex),c.getString(titleIndex),c.getString(artistIndex),c.getString(albumIndex),c.getString(timeIndex),c.getInt(playcountIndex),color);
// Add to song the data from your cursor
publishProgress(song);
if (color == 0xFFdfe8ea) {
color = 0xFFf2f8fa;
} else {
color = 0xFFdfe8ea;
}
} while (c.moveToNext());
}
return null;
}
#Override
protected void onPostExecute(Void item) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Song... items) {
for (Song song : items) {
TableRow tr = new TableRow(MainActivity.this);
tr.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
TextView space = new TextView(MainActivity.this);
space.setText("");
space.setBackgroundColor(song.color); //0xFFf2f8fa alternating
space.setSingleLine();
space.setPadding(2, 2, 2, 2);
space.setGravity(Gravity.LEFT);
space.setTextColor(0xFF000000);
space.setLayoutParams(new LayoutParams(
findViewById(R.id.spaceColumn).getWidth(),
LayoutParams.WRAP_CONTENT));
/* Create a Button to be the row-content. */
TextView title = new TextView(MainActivity.this);
title.setText(song.title);
title.setBackgroundColor(song.color); //0xFFf2f8fa alternating
title.setSingleLine();
title.setPadding(2, 2, 2, 2);
title.setGravity(Gravity.LEFT);
title.setTextColor(0xFF000000);
title.setEllipsize(TruncateAt.END);
title.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Create a Button to be the row-content. */
TextView artist = new TextView(MainActivity.this);
artist.setText(song.artist);
artist.setBackgroundColor(song.color); //0xFFf2f8fa alternating
artist.setSingleLine();
artist.setPadding(2, 2, 2, 2);
artist.setGravity(Gravity.LEFT);
artist.setTextColor(0xFF000000);
artist.setEllipsize(TruncateAt.END);
artist.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Create a Button to be the row-content. */
TextView time = new TextView(MainActivity.this);
time.setText(song.time);
time.setBackgroundColor(song.color); //0xFFf2f8fa alternating
time.setSingleLine();
time.setPadding(2, 2, 2, 2);
time.setGravity(Gravity.LEFT);
time.setTextColor(0xFF000000);
time.setLayoutParams(new LayoutParams(
findViewById(R.id.timeColumn).getWidth(),
LayoutParams.WRAP_CONTENT));
/* Create a Button to be the row-content. */
TextView album = new TextView(MainActivity.this);
album.setText(song.album);
album.setBackgroundColor(song.color); //0xFFf2f8fa alternating
album.setSingleLine();
album.setPadding(2, 2, 2, 2);
album.setGravity(Gravity.LEFT);
album.setTextColor(0xFF000000);
album.setEllipsize(TruncateAt.END);
album.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Add Button to row. */
tr.addView(space);
tr.addView(title);
tr.addView(artist);
tr.addView(time);
tr.addView(album);
// Add the row to the table
((TableLayout) findViewById(R.id.tableLayout)).addView(tr, new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
}
}
The reason you are seeing this RejectedExceutionException is almost certainly because you are submitting too many requests.
I just went into the code of AsyncTask and I noticed:
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 1;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(10);
/**
* An {#link Executor} that can be used to execute tasks in parallel.
*/
public static final Executor THREAD_POOL_EXECUTOR
= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
That will build a bounded LinkedBlockingQueue. Up to 10 elements for the bound. The
MAXIMUM_POOL_SIZE I saw was 128 (which means if needed the Executor will create 128 threads at most).
Once you exceed the 128 thread and submit to a new MyTask instance with a queue depth of 10 you will get a RejectedExecutionException. This exception is thrown when you saturate all available threads and there is no more room on the queue.
You can easily confirm this by getting a thread-dump when the RejectedExecution occurs.
Basically, you can submit 138 MyTask's at any particular time but once you submit 139+ at the same time (not within the life time of the app) you will run into this issue
Edit: I went through the code more, and the most recent version (actually since Jan 16, 2011) this error should never happen.
With any version older then that you will run into this issue.
In short, if you upgrade you version this issue will go away, however each task will be executed serially and not concurrently.
If you want to do it using an AsyncTask, consider using publishProgress(), that way each item will be added as it is fetched from the database. This way:
NOTE: Consider that Song is a class with name, album, artist and time attributes.
class MyAsyncTask extends AsyncTask<Void, Song, Void> {
#Override
protected Void doInBackground(Void... params) {
myDB.execSQL("CREATE TABLE IF NOT EXISTS "
+ TableName
+ " (_id INTEGER PRIMARY KEY, filepath TEXT UNIQUE, title TEXT, artist TEXT, album TEXT, time TEXT, playcount NUMERIC);");
Cursor c = myDB.rawQuery("SELECT * FROM " + TableName, null);
c.moveToFirst();
if (c != null) {
int color = 0xFFdfe8ea;
this.startManagingCursor(c);
// Loop through all Results
do {
Song song = new Song();
// Add to song the data from your cursor
publishProgress(song);
} while (c.moveToNext());
}
return null;
}
#Override
protected void onPostExecute(Void item) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Song... items) {
for (Song song : items) {
TableRow tr = new TableRow(MainActivity.this);
tr.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
TextView space = new TextView(MainActivity.this);
space.setText("");
space.setBackgroundColor(color); //0xFFf2f8fa alternating
space.setSingleLine();
space.setPadding(2, 2, 2, 2);
space.setGravity(Gravity.LEFT);
space.setTextColor(0xFF000000);
space.setLayoutParams(new LayoutParams(
findViewById(R.id.spaceColumn).getWidth(),
LayoutParams.WRAP_CONTENT));
/* Create a Button to be the row-content. */
TextView title = new TextView(MainActivity.this);
title.setText(song.getTitle());
title.setBackgroundColor(color); //0xFFf2f8fa alternating
title.setSingleLine();
title.setPadding(2, 2, 2, 2);
title.setGravity(Gravity.LEFT);
title.setTextColor(0xFF000000);
title.setEllipsize(TruncateAt.END);
title.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Create a Button to be the row-content. */
TextView artist = new TextView(MainActivity.this);
artist.setText(song.getArtist());
artist.setBackgroundColor(color); //0xFFf2f8fa alternating
artist.setSingleLine();
artist.setPadding(2, 2, 2, 2);
artist.setGravity(Gravity.LEFT);
artist.setTextColor(0xFF000000);
artist.setEllipsize(TruncateAt.END);
artist.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Create a Button to be the row-content. */
TextView time = new TextView(MainActivity.this);
time.setText(song.getTime());
time.setBackgroundColor(color); //0xFFf2f8fa alternating
time.setSingleLine();
time.setPadding(2, 2, 2, 2);
time.setGravity(Gravity.LEFT);
time.setTextColor(0xFF000000);
time.setLayoutParams(new LayoutParams(
findViewById(R.id.timeColumn).getWidth(),
LayoutParams.WRAP_CONTENT));
/* Create a Button to be the row-content. */
TextView album = new TextView(MainActivity.this);
album.setText(song.getAlbum());
album.setBackgroundColor(color); //0xFFf2f8fa alternating
album.setSingleLine();
album.setPadding(2, 2, 2, 2);
album.setGravity(Gravity.LEFT);
album.setTextColor(0xFF000000);
album.setEllipsize(TruncateAt.END);
album.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Add Button to row. */
tr.addView(space);
tr.addView(title);
tr.addView(artist);
tr.addView(time);
tr.addView(album);
// Add the row to the table
((TableLayout) findViewById(R.id.tableLayout)).addView(tr, new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
}
}
I believe you understood the concept behind AsyncTask wrongly, I strongly suggest you reread its documentation at Android Developers as its concept is a bit tricky to understand but very powerfull when you do so. As Romain Guy commented on your answer you can only execute UI code on the onPreExecute(), onProgressUpdate() and onPostExecute() methods.
I dont think you need to create one AsyncTask for that. You are not fetching anything from the network or downloading images. Its just standard loading.
I would limit the result in the SQL with 'limit'.
Also, you are doing that inside an adapter right? Because I think you are adding everything to the list, where you should create a listview in your layout and set an Adapter. Maybe extending BaseAdapter.
Every adapter has a convenient method called getView that will get called only when it is visible and should help with your problem.
This is an example of an adapter:
public class MyAdapter extends BaseAdapter {
private Context context = null;
private Cursor cursor;
public MyAdapter(Context context){
this.context = context;
SQLiteDatabase db = DatabaseHelper.getInstance(context).getReadableDatabase();
this.cursor = db.query("YOUR QUERY");
}
#Override
public int getCount() {
return this.cursor.getCount();
}
public Cursor getCursor() {
return cursor;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout row;
try {
cursor.moveToPosition(position);
if (convertView == null) {
row = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.myRowLayout, parent, false);
} else {
row = (LinearLayout) convertView;
}
TextView name = (TextView) row.findViewById(R.id.myLayoutId);
name.setText(cursor.getString(cursor.getColumnIndex("your column")));
} catch (Exception e) {
row = null;
Log.e(LOG_TAG, "" + e.getMessage());
e.printStackTrace();
}
return row;
}
#Override
public MoneyCurrency getItem(int position) {
this.cursor.moveToPosition(position);
long id = this.cursor.getLong(this.cursor.getColumnIndex("your column id"));
return new Object.read(id, context, null); //Return whatever you want to show in that row. This is used if you want to use onClick listeners or menus
}
#Override
public long getItemId(int position) {
this.cursor.moveToPosition(position);
return this.cursor.getLong(this.cursor.getColumnIndex("your id column"));
}
}

Categories

Resources