和SimpleCursorAdapter有關的小問題


今天學習sqlite的時候,用到了simpleCursorAdapter.SimpleCursorAdapter是Android專門為了連接數據庫與視圖而產生的。他是將從數據庫表中獲取的數據顯示到ListView的橋梁。按照網上教程,我利用ListView體現SimpleCursorAdapter的用法。

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);

但是,調試的時候應用報錯,column '_id' does not exist。然后才看到教程里寫必須要求我們的數據庫中有一列,_id;SimpleCursorAdapter非常傲嬌, 如果沒有這列,就不干了

  還有兩個問題,1.SimpleCursorAdapter 中間出現了一道橫線,那說明這個函數已經過時,代替的函數是什么.2.當數據庫數據更新時,使用adapter.notifyDataSetChanged(),列表並未更新,那么如何保證UI及時更新?

 找到的代替SimplecursorAdapter構造方法的函數是:SimpleCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to,int flags) 相較於之前的,僅僅多了一個 flags。flags在這里是用來標識當數據發生改變調用onContentChanged()的時候是否通知ContentProvider數據改變。對應有兩個常數:CursorAdapter。FLAG_AUTO_REQUERY和CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER。前者在api11后不推薦使用,就不在敘述。后者的作用是在 Cursor 上注冊一個內容監測器,並在其發出通知時調用 onContentChanged() 方法。

如果無需監聽ContentProvider的改變,或者,在CursorAdapter中使用了CursorLoader(他會為你注冊一個內容監測器),則可以傳0。

在UI更新方面,我找到三個方法:

cursor.requery();
adapter.notifyDataSetChanged();

 

adapter.swapCursor(newCursor);
adapter.notifyDataSetChanged();

 

adapter.changeCursor(newCursor);
adapter.notifyDataSetChanged();

 

第一種方法,requery被畫上了橫線,並且這個方法測試失敗了。
第二種方法和第三種方法都成功了。查閱資料,swapCursor和changeCursor兩種方法的區別介紹如下:

 

 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 cursor
17 notifyDataSetChanged();
18 } else {
19 mRowIDColumn = -1;
20 mDataValid = false;
21 // notify the observers about the lack of a data set
22 notifyDataSetInvalidated();
23 }
24 return oldCursor;
25 }

swapCursor 交換了一個新的 Cursor,返回舊的Cursor,它並未將舊Cursor關閉

 

1 public void changeCursor(Cursor cursor) {
2         Cursor old = swapCursor(cursor);
3         if (old != null) {
4             old.close();
5         }
6     }

 


changeCursor則替換將原來的 Cursor關閉了。

如果使用了CursorLoader(這真是一個好東西),它會管理Cursor,不需要我們自己關閉Cursor,loader會完成。我們只需實現下面三種方法即可

 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 loading
10 public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
11 // Swap the new cursor in. (The framework will take care of closing the
12 // old cursor once we return.)
13 mAdapter.swapCursor(data);
14 }
15 
16 // Called when a previously created loader is reset, making the data unavailable
17 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 no
20 // longer using it.
21 mAdapter.swapCursor(null);

 

參考資料: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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM