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
Android V21 Theme.Appcompat Color Accent Is Ignored, No Padding on Dialogs
Audio Format for iOS and Android
Set Starting Height of Collapsingtoolbarlayout
Httpurlconnection.Openconnection Fails Second Time
How to Store Object in Sqlite Database
How to Place App Icon on Launcher Home Screen
Using Google Places API in Android
How to Set Status Bar Background as Gradient Color or a Drawable in Android
Sending Message to a Handler on a Dead Thread When Getting a Location from an Intentservice
Using Espresso to Unit Test Google Maps
Access The Sim Card with an Android Application
How to Pause Android.Speech.Tts.Texttospeech
How to Capture Key Events from Bluetooth Headset with Android
Android Studio Keyboard Shortcut Control
How to Use The Limit Argument in an Sqlite Query with Android