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

You may also like...

退出移动版