How to manipulate cursor data before displaying it in ListView (using Loader)?

Each element of my SherlockListFragment contains 3 TextView : a name and two numbers. The data comes from the objective table of my database, which has the following structure:

 CREATE TABLE objective ( _id INTEGER PRIMARY KEY, id_project INTEGER NOT NULL, activity_code INTEGER NOT NULL, day_duration INTEGER NOT NULL, week_frequency INTEGER NOT NULL, FOREIGN KEY(id_project) REFERENCES project(id_project) ); 

In addition, I read that filling the list with the cursor should be done using the loader (especially when using the database, since this can be a very slow operation). I have found the SimpleCursorLoader class https://stackoverflow.com/a/166269/2126328 , but it directly displays the data in the field.

This is not exactly what I want, because, as you can see, in my objective table I have activity_code . Therefore, I would like to replace it with a string (I have an Enum that lists all my activity codes and returns a string resource identifier for each of them).

Do you know how I can manipulate data before it is displayed in a TextView ?

Here is my SherlockListFragment

 public class ObjectivesDisplayFragment extends SherlockListFragment implements LoaderManager.LoaderCallbacks<Cursor> { private Activity activity; private SimpleCursorAdapter adapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.objectives_display, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); activity = getActivity(); String[] columns = new String[] { "activity_code", "day_duration", "week_frequency" }; int[] to = new int[] { R.id.activityName, R.id.objectiveDuration, R.id.objectiveFrequency }; getLoaderManager().initLoader(0x01, null, this); adapter = new SimpleCursorAdapter(activity.getApplicationContext(), R.layout.objective_row, null, columns, to, SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); setListAdapter(adapter); } public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { return new SimpleCursorLoader(activity) { @Override public Cursor loadInBackground() { DatabaseHelper dbHelper = DatabaseHelper.getInstance(activity); String query = "SELECT _id, activity_code, day_duration, week_frequency FROM objective WHERE id_project = ?"; String[] args = new String[] { "1" }; // projectId Cursor results = dbHelper.getReadableDatabase().rawQuery(query, args); return results; } }; } public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) { adapter.swapCursor(cursor); } public void onLoaderReset(Loader<Cursor> arg0) { adapter.swapCursor(null); } } 

EDIT: I don't need to close the cursor and database in SimpleCursorLoader> loadInBackground, right? Otherwise, the data could not be read. That is, the close operation is automatically processed or do I need to do it myself in another place?

+4
source share
1 answer

I think this might work for you:

 adapter.setViewBinder(new ViewBinder(){ @Override public boolean setViewValue(View view, Cursor cursor, int columnIndex) { String label = "Inactive"; if(columnIndex == 4) { if(cursor.getInt(columnIndex) == 1) { label = "Active"; } TextView tv = (TextView) view.findViewById(R.id.status); tv.setText(label); return true; } return false; } }); setListAdapter(adapter); 

Background information: I had a foreign key column (integer) in the table and he wanted to allow it a string value (from a linked table) when populating it as a list. The column was in the 4th index (the 5th column in the set), so I just used setViewBinder () to control the required column.

Further, my layout had 5 textual representations to display 5 fields from the cursor. One thing also NOTICEABLE here is that when using "if" conditions to catch the column indices, make sure that each conditional block must contain "return true". In this case, when the interpreter reaches "return false" - means that your field has not received manipulation.

I am sure that the above block of code is pretty simple and straightforward.

+3
source

All Articles