SimpleCursorAdapter is a small problem related to simplecursoradapter.
When learning sqlite today, simpleCursorAdapter. SimpleCursorAdapter was used by Android to connect to databases and views. It is a bridge to display the data obtained from the database table to ListView. According to the online tutorial, I use ListView to demonstrate SimpleCursorAdapter usage.
1 ListView list=(ListView)findViewByID(R.id.listview);2 SQLiteDatabase dbread=db.getReadableDatabase();3 Cursor cur=dbread.query("user",null,null,null,null,null,null);4 adapter=new SimpleCursorAdapter(this,R.layout.layout,cur,new String[]{"name","sex"},new int[]{R.id.name,R.id.sex});5 listview.setAdapter(sca);
However, when debugging, the application reports an error, column '_ id' does not exist. Then we can see that in the tutorial, there must be a column in our database, _ id; SimpleCursorAdapter is very proud. If this column is not available, we will not do it.
There are two more questions: 1. there is a horizontal line in the middle of SimpleCursorAdapter, which indicates that this function is out of date. What is the replaced function. 2. when the database data is updated, use the adapter. notifyDataSetChanged (), the list is not updated, so how to ensure that the UI is updated in a timely manner?
The functions found to replace the SimplecursorAdapter constructor are: SimpleCursorAdapter (Context context, int layout, Cursor c, String [] from, int [] to, int flags) compared with the previous one, there is only one more flags. Flags is used to identify whether to notify ContentProvider of data changes when onContentChanged () is called when data changes. The pair should have two constants: CursorAdapter. FLAG_AUTO_REQUERY and CursorAdapter. FLAG_REGISTER_CONTENT_OBSERVER. The former is not recommended after api11, so it is not described. The latter registers a Content Monitor on the Cursor and calls the onContentChanged () method when it sends a notification.
If you do not need to listen for changes to ContentProvider, or use CursorLoader in CursorAdapter (he will register a Content Monitor for you), you can pass 0.
In terms of UI update, I have found three methods:
cursor.requery();adapter.notifyDataSetChanged();
adapter.swapCursor(newCursor);adapter.notifyDataSetChanged();
adapter.changeCursor(newCursor);adapter.notifyDataSetChanged();
In the first method, the requery is drawn on a horizontal line, and this method fails to be tested.
Both method 2 and method 3 are successful. For details, the differences between swapCursor and changeCursor are as follows:
1 public Cursor swapCursor(Cursor newCursor) { 2 if (newCursor == mCursor) { 3 return null; 4 } 5 Cursor oldCursor = mCursor; 6 if (oldCursor != null) { 7 if (mChangeObserver != null) oldCursor.unregisterContentObserver(mChangeObserver); 8 if (mDataSetObserver != null) oldCursor.unregisterDataSetObserver(mDataSetObserver); 9 }10 mCursor = newCursor;11 if (newCursor != null) {12 if (mChangeObserver != null) newCursor.registerContentObserver(mChangeObserver);13 if (mDataSetObserver != null) newCursor.registerDataSetObserver(mDataSetObserver);14 mRowIDColumn = newCursor.getColumnIndexOrThrow("_id");15 mDataValid = true;16 // notify the observers about the new cursor17 notifyDataSetChanged();18 } else {19 mRowIDColumn = -1;20 mDataValid = false;21 // notify the observers about the lack of a data set22 notifyDataSetInvalidated();23 }24 return oldCursor;25 }
SwapCursor exchanges a new Cursor and returns the old Cursor. It does not close the old Cursor.
1 public void changeCursor(Cursor cursor) {2 Cursor old = swapCursor(cursor);3 if (old != null) {4 old.close();5 }6 }
ChangeCursor is replaced with the original Cursor.
If you use CursorLoader (this is really a good thing), it will manage Cursor. We don't need to close Cursor ourselves, and the loader will complete. We only need to implement the following three methods:
1 // Called when a new Loader needs to be created 2 public Loader<Cursor> onCreateLoader(int id, Bundle args) { 3 // Now create and return a CursorLoader that will take care of 4 // creating a Cursor for the data being displayed. 5 return new CursorLoader(this, ContactsContract.Data.CONTENT_URI, 6 PROJECTION, SELECTION, null, null); 7 } 8 9 // Called when a previously created loader has finished loading10 public void onLoadFinished(Loader<Cursor> loader, Cursor data) {11 // Swap the new cursor in. (The framework will take care of closing the12 // old cursor once we return.)13 mAdapter.swapCursor(data);14 }15 16 // Called when a previously created loader is reset, making the data unavailable17 public void onLoaderReset(Loader<Cursor> loader) {18 // This is called when the last Cursor provided to onLoadFinished()19 // above is about to be closed. We need to make sure we are no20 // longer using it.21 mAdapter.swapCursor(null);
References: http://stackoverflow.com/questions/11093380/what-to-set-cursoradaptercontext-context-cursor-c-int-flags-to-in-order-to-m
Http://www.blogc.at/2014/03/03/swapcursor-vs-changecursor-whats-the-difference/
Http://developer.android.com/reference/android/widget/CursorAdapter.html#CursorAdapter (android. content. Context, android. database. Cursor, int)