Changing Values from Cursor Using Simplecursoradapter

Changing values from Cursor using SimpleCursorAdapter


The simplest way to format a cursor value is to use SimpleCursorAdapter.setViewBinder(..):

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.list, cursor,
new String[] { Definition.Item.TITLE, Definition.Item.CREATE_DATE }, new int[] { R.id.title, R.id.createDate});

adapter.setViewBinder(new ViewBinder() {

public boolean setViewValue(View aView, Cursor aCursor, int aColumnIndex) {

if (aColumnIndex == 2) {
String createDate = aCursor.getString(aColumnIndex);
TextView textView = (TextView) aView;
textView.setText("Create date: " + MyFormatterHelper.formatDate(getApplicationContext(), createDate));
return true;
}

return false;
}
});

Modifying SimpleCursorAdapter's data

You can do something like this:

adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, int column) {
if( column == 0 ){ // let's suppose that the column 0 is the date
TextView tv = (TextView) view;
String dateStr = cursor.getString(cursor.getColumnIndex("name_of_the_date_column"));
// here you use SimpleDateFormat to bla blah blah
tv.setText(theFormatedDate);
return true;
}
return false;
}
});

Change text of items in ListView when it is displayed using SimpleCursorAdapter

SimpleCursorAdapter.ViewBinder did the job. As answered here, I changed the code to..

Cursor allTaskcursor = databaseHelper.getAllTasks();
String[] from = {"name", "date"};
int[] to = new int[] {android.R.id.text1, android.R.id.text2};
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(context, android.R.layout.simple_list_item_2, allTaskcursor, from, to, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
cursorAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if (view.getId() == android.R.id.text2) {
int getIndex = cursor.getColumnIndex("date");
int date = cursor.getInt(getIndex);
TextView dateTextView = (TextView) view;
dateTextView.setText(date + " days");
return true;
}
return false;
}
});
allTaskListView.setAdapter(cursorAdapter);

Android SimpleCursorAdapter doesn't update when database changes

Call requery() on the Cursor when you change data in the database that you want reflected in that Cursor (or things the Cursor populates, like a ListView via a CursorAdapter).

A Cursor is akin to an ODBC client-side cursor -- it holds all of the data represented by the query result. Hence, just because you change the data in the database, the Cursor will not know about those changes unless you refresh it via requery().


UPDATE: This whole question and set of answers should be deleted due to old age, but that's apparently impossible. Anyone seeking Android answers should bear in mind that the Android is a swiftly-moving target, and answers from 2009 are typically worse than are newer answers.

The current solution is to obtain a fresh Cursor and use either changeCursor() or swapCursor() on the CursorAdapter to affect a data change.

Using SimpleCursorAdapter.ViewBinder to change the color of TextView

From the Android documentation on SimpleCursorAdapter.ViewBinder:

Binds the Cursor column defined by the specified index to the
specified view. When binding is handled by this ViewBinder, this
method must return true. If this method returns false,
SimpleCursorAdapter will attempts to handle the binding on its own.

In other words, your implementation of setViewValue should not be specific to any one View, as SimpleCursorAdapter will make changes to each View (according to your implementation) when it populates the ListView. setViewValue is basically your chance to do whatever you wish with the data in your Cursor, including setting the color of your views. Try something like this,

public boolean setViewValue(View view, Cursor cursor, int columnIndex){    
// if this holds true, then you know that you are currently binding text to
// the TextView with id "R.id.alarmName"
if (view.getId() == R.id.alarmName) {
final int dayOfWeekIndex = cursor.getColumnIndex("day_of_week");
final int color = cursor.getInt(dayOfWeekIndex);

switch(color) {
case 0: ((TextView) view).setTextColor(Color.RED); break;
case 1: /* ... */ break;
case 2: /* ... */ break;
/* etc. */
}
return true;
}
return false;
}

Note that the above code assumes a column named "day_of_week" which holds an int value 0-6 (to specify the specific day of the week).

Change the number display in SimpleCursorAdapter

Since you are using datatype as real , and storing it into db as real number. At the time of storing into SqliteDB, it converts it into exponential format. When you are trying to read it from database it gives you the converted exponential format into string. You just change the datatype to varchar for costo. It will solve your problem.

SimpleCursorAdapter with ImageView and TextView

When the view to bind is an ImageView and there is no existing ViewBinder associated SimpleCursorAdapter.bindView() calls setViewImage(ImageView, String).
By default, the value will be treated as an image resource. If the value cannot be used as an image resource, the value is used as an image Uri.

If you need to filter in other ways the value retrieved from the database you need a ViewBinder to add to the ListAdapter as follow:

listAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder(){
/** Binds the Cursor column defined by the specified index to the specified view */
public boolean setViewValue(View view, Cursor cursor, int columnIndex){
if(view.getId() == R.id.your_image_view_id){
//...
((ImageView)view).setImageDrawable(...);
return true; //true because the data was bound to the view
}
return false;
}
});

Get selected item from ListView bound with SimpleCursorAdapter

So a couple of points: after you fetch the cursor, you want to call startManagingCursor. This ties the cursor's lifecycle with Activity's lifecycle (so when the Activity gets destroyed the cursor gets closed/cleaned up).

startManagingCursor(c);
ListAdapter adapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
c,
new String[] {"name"},
new int[] {android.R.id.text1});
setListAdapter(adapter);

Also, the database isn't closed, the Cursor typically keeps a live connection to the DB (so the ListView can scroll and do things of that nature that may require future access to the Cursor's contents.

To your core question, the easiest way to do it in onListItemClick is this:

Cursor c = ((SimpleCursorAdapter)l.getAdapter()).getCursor();
c.moveToPosition(position);

You can then use the c.getLong(0) to get the id (assuming you fetched the id column as the first column which is generally the case). However, note that the id is passed in as part of the signature (see the last argument in public void onListItemClick(ListView l, View v, int position, long id)) so you really don't need to fetch it again (but you certainly can if you want to burn the cycles). For accessing other columns you can do the same thing, just change the column index.

Android, using SimpleCursorAdapter to set colour not just strings

Check out SimpleCursorAdapter.ViewBinder.

setViewValue is basically your chance to do whatever you wish with the data in your Cursor, including setting the background color of your views.

For example, something like:

SimpleCursorAdapter.ViewBinder binder = new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
String name = cursor.getColumnName(columnIndex);
if ("Colour".equals(name)) {
int color = cursor.getInt(columnIndex);
view.setBackgroundColor(color);
return true;
}
return false;
}
}
datasource.setViewBinder(binder);

Update - if you're using a custom adapter (extending CursorAdaptor) then the code doesn't change a whole lot. You'd be overriding getView and bindView:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView != null) {
return convertView;
}
/* context is the outer activity or a context saved in the constructor */
return LayoutInflater.from(context).inflate(R.id.my_row);
}

@Override
public void bindView(View view, Context context, Cursor cursor) {
int color = cursor.getInt(cursor.getColumnIndex("Colour"));
view.setBackgroundColor(color);
String label = cursor.getString(cursor.getColumnIndex("GenreLabel"));
TextView text = (TextView) findViewById(R.id.genre_label);
text.setText(label);
}

You're doing a bit more manually, but it's more or less the same idea. Note that in all of these examples you might save on performance by caching the column indices instead of looking them up via strings.



Related Topics



Leave a reply



Submit