2012年4月15日 星期日

Cursor, MergeCursor, MatrixCursor

新開了這個blog,用來記錄一下程式的相關筆記

主要是希望可以讓我這個有初老症的叔叔查閱用的

第一篇就來說說List跟Cursor吧

Cursor這基本的類別用法就不多說了,直接介紹一下MergeCursor

MergeCursor可以用來merge多個Cursor,只要在new MergeCursor時將Cursor Array帶入即可
void startQuery() { imageCursor = this.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageProject, null, null, MediaStore.Images.Media.BUCKET_DISPLAY_NAME + " ASC, " + MediaStore.Images.Media.DISPLAY_NAME + " ASC"); videoCursor = this.getContentResolver().query( MediaStore.Video.Media.EXTERNAL_CONTENT_URI, videoProject, null, null, MediaStore.Video.Media.BUCKET_DISPLAY_NAME + " ASC, " + MediaStore.Video.Media.DISPLAY_NAME + " ASC"); mediaCursor = new MergeCursor(new Cursor[] {videoCursor, imageCursor}); tmpAdapter1.changeCursor(mediaCursor); }

imageCursor裡的data是手機中所有的image,按照bucket name(album name)以及image name排序

假設有四張image,分別的bucket name及image name為
{camera, test1}
{photo, ha}
{photo, zzz}
{camera, abc123}


query得到的結果會是
{camera, abc123}
{camera, test1}
{photo, ha}
{photo, zzz}

videoCursor裡的data是手機中所有的video

mediaCursor將這兩個cursor merge在一起,之後就可以直接拿來用

當然merge之後所有的data並不會再排序過,裡面data會是video data再接著image data

對我來說沒辦法再sort算是MergeCursor的一個小缺點,常常想要用它又沒辦法用阿!!

接下來介紹MatrixCursor,這個類別可以讓你建立一個cursor而且自己建立裡面的data

如果data並不是cursor但卻又有需要將它變成cursor的需求,就可以用Matrix Cursor
String[] cloumns = new String[] {"id", "name", "phone" }; MatrixCursor matrixCursor = new MatrixCursor(cloumns); startManagingCursor(matrixCursor); matrixCursor.addRow(new Object[] { 1, "Mike", 123456 }); matrixCursor.addRow(new Object[] { 2, "wahaha", 654321 });
使用上很簡單,只要是透過addRow將data帶入建立cursor

最後再來講一個小技巧,當將多個Cursor merge在一起後

可以透過query時多帶入一個projection欄位

靠此欄位來方便判斷data為哪一個cursor

以imageCursor跟videoCursor為例
String[] imageProject = new String[] { "'image' as type", MediaStore.Images.Media._ID, MediaStore.Images.Media.BUCKET_DISPLAY_NAME, MediaStore.Images.Media.DISPLAY_NAME }; String[] videoProject = new String[] { "'video' as type", MediaStore.Video.Media._ID, MediaStore.Video.Media.BUCKET_DISPLAY_NAME, MediaStore.Video.Media.DISPLAY_NAME }; ... int index = cursor.getColumnIndex("type"); String type = cursor.getString(index); text1.setText(type);
projection多帶入一個"'image as type'" ("'video as type'"),就等於多了一個欄位type

imageCursor裡type欄位的值就是'image',videoCursor裡type欄位的值就是video

好用的小技巧,方便判斷data是屬於哪一個Cursor

最後補充一下每個要merge的各個cursor projection可以完全不同

但要get data之前最好先用getColumnIndex()取得column index再get data

避免取得錯誤的資料(如無此column, getColumnIndex會回傳 -1)

沒有留言:

張貼留言