Cursor排序
需求:
数据库搜索联系人‘张’搜索出的结果按照关键字匹配先后进行排序,把‘张三’放在‘小张’前面。
而数据库可实现的是按照拼音首字母排序‘小张’排在‘张三’前面。
需要对获取的Cursor再进行排序。但由于Cursor无法编辑,因此需要曲线救国,写一个继承CursorWrapper的类,在里面将Cursor对应的下标,排序字段等数据放入一个List中。排序此List,复写CursorWrapper的moveToPosition,moveToNext等方法。即可实现Cursor排序。
相当于将Cursor重新封装了一层,穿了身衣服。
SortCursor代码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import android.database.Cursor;
import android.database.CursorWrapper
/**
* 用来重新排序Cursor,按照高亮字匹配姓名的先后排序。
* 例如:搜索'张',结果'张三'排'小张'前。
* @author SmartTiger
* 2016-02-23
*/
public class SortCursor extends CursorWrapper implements Comparator<SortEntry>{
public SortCursor(Cursor cursor) {
super(cursor);
}
Cursor mCursor;
ArrayList<SortEntry> sortList = new ArrayList<SortEntry>();
int mPos = -1;
public static class SortEntry {
public int key; //根据这个key排序。
public int order; //相当于原始cursor的指针。
}
@Override
public int compare(SortEntry entry1, SortEntry entry2) {
//解决关键字为数字时,把姓名匹配为-1的排最前面的问题。
if(entry1.key != entry2.key )
if(entry1.key == -1)
return 1;
else if(entry2.key == -1)
return -1;
return entry1.key - entry2.key;
}
public SortCursor(Cursor cursor, int nameColumnIndex, String searchKey) {
super(cursor);
mCursor = cursor;
if (mCursor != null && mCursor.getCount() > 0) {
int i = 0;
for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext(), i++) {
SortEntry sortKey = new SortEntry();
String name = cursor.getString(nameColumnIndex);
if(name != null)
sortKey.key = name.indexOf(searchKey);
else
sortKey.key = -1;
System.out.println("name--"+name+"--sortKey.key=="+sortKey.key);
sortKey.order = i;
sortList.add(sortKey);
}
}
Collections.sort(sortList, this);
}
public boolean moveToPosition(int position) {
if (position >= 0 && position < sortList.size()) {
mPos = position;
int order = sortList.get(position).order;
return mCursor.moveToPosition(order);
}
if (position < 0) {
mPos = -1;
}
if (position >= sortList.size()) {
mPos = sortList.size();
}
return mCursor.moveToPosition(position);
}
public boolean moveToFirst() {
return moveToPosition(0);
}
public boolean moveToLast() {
return moveToPosition(getCount() - 1);
}
public boolean moveToNext() {
return moveToPosition(mPos + 1);
}
public boolean moveToPrevious() {
return moveToPosition(mPos - 1);
}
public boolean move(int offset) {
return moveToPosition(mPos + offset);
}
public int getPosition() {
return mPos;
}
}
使用方法,只需在要排序的Cursor处添加下面代码即可。
调用代码:
cursor = new SortCursor(cursor, PHONE_PRIMARY_DISPLAY_NAME_COLUMN_INDEX, queryString);
参数cursor为要排序的对象,
参数PHONE_PRIMARY_DISPLAY_NAME_COLUMN_INDEX为要排序字段的index,目的通过Cursor获取到姓名(张三,小张)。
参数queryString为搜索的关键字(‘张’)
返回的直接就是排序好的cursor,Cursor的所有方法都支持。
调试代码:
private static final String[] CONTACTS_PROJECTION_PRIMARY = new String[] {
Contacts._ID, // 0
Contacts.DISPLAY_NAME_PRIMARY, // 1
Contacts.CONTACT_PRESENCE, // 2
Contacts.CONTACT_STATUS, // 3
Contacts.PHOTO_ID, // 4
Contacts.PHOTO_THUMBNAIL_URI, // 5
Contacts.LOOKUP_KEY // 6
};
public static final int CONTACT_ID = 0;
public static final int CONTACT_DISPLAY_NAME = 1;
public static final int CONTACT_PRESENCE_STATUS = 2;
public static final int CONTACT_CONTACT_STATUS = 3;
public static final int CONTACT_PHOTO_ID = 4;
public static final int CONTACT_PHOTO_URI = 5;
public static final int CONTACT_LOOKUP_KEY = 6;
String where = Contacts.DISPLAY_NAME_PRIMARY + " LIKE '%"+filter+"%'";
Cursor cursor = context.getContentResolver().query(Contacts.CONTENT_URI, CONTACTS_PROJECTION_PRIMARY, where, null, Contacts.SORT_KEY_PRIMARY);
cursor = new SortCursor(cursor, CONTACT_DISPLAY_NAME, queryString);
再添加两个小知识:
Contacts.CONTENT_STREQUENT_URI—–筛选出收藏联系人加常用联系人。
Contacts.CONTENT_FREQUENT_URI—-筛选常用联系人
当使用这里两个时,排序设置为Contacts.SORT_KEY_PRIMARY就不是按照姓名了。似乎是按照呼出频率排序的。
设置排序字段是Contacts.SORT_KEY_PRIMARY时。这个可以不在Projection数组里。也能按照这个排序。
注意:
当Projection里用Contacts.DISPLAY_NAME时使用Contacts.SORT_KEY_PRIMARY
当Projection里用display_name_alt时使用Contacts.SORT_KEY_ALTERNATIVE
转载自:https://blog.csdn.net/xiaoxiaohude/article/details/51597282