Android Contact 关于字母分组的实现 的简单说明

1. 效果, 即是C D 等等的字母分组。

 

2.实现

在ContactListActivity.java 中的

 private final class ContactItemListAdapter extends CursorAdapter
            implements SectionIndexer, OnScrollListener, PinnedHeaderListView.PinnedHeaderAdapter

主要实现。 此类中有一个开关,用于打开和关闭 SectionHeaders的显示。

 private boolean mDisplaySectionHeaders = true;


在其getView()方法中,有调用方法bindSectionHeader()用于处理SectionHeader的显示。

private void bindSectionHeader(View itemView, int position, boolean displaySectionHeaders) {
    final ContactListItemView view = (ContactListItemView)itemView;
    final ContactListItemCache cache = (ContactListItemCache) view.getTag();
    if (!displaySectionHeaders) {
        view.setSectionHeader(null);
        view.setDividerVisible(true);
    } else {
        final int section = getSectionForPosition(position);
        if (getPositionForSection(section) == position) {
            String title = (String)mIndexer.getSections()[section];
            view.setSectionHeader(title);
        } else {
            view.setDividerVisible(false);
            view.setSectionHeader(null);
        }

        // move the divider for the last item in a section
        if (getPositionForSection(section + 1) - 1 == position) {
            view.setDividerVisible(false);
        } else {
            view.setDividerVisible(true);
        }
    }
}

ContactListItemView 是一个包含有SectionHeader的view, 可以设置其显示与不显示。通过判断目前位置是否为此SectionHeader纪录的第一条纪录, 如果是则显示SectionHeader, 如果不是则不显示。

 

分组的主要实现通过下面这个类。

public class ContactsSectionIndexer implements SectionIndexer;

//构造函数如下  

public ContactsSectionIndexer(String[] sections, int[] counts) {         if (sections == null || counts == null) {             throw new NullPointerException();         }

        if (sections.length != counts.length) {             throw new IllegalArgumentException(                     "The sections and counts arrays must have the same length");         }

        // TODO process sections/counts based on current locale and/or specific section titles

        this.mSections = sections;         mPositions = new int[counts.length];         int position = 0;         for (int i = 0; i < counts.length; i++) {             if (mSections[i] == null) {                 mSections[i] = " ";             } else {                 mSections[i] = mSections[i].trim();             }             Log.e("Contact", "mSections["+i+"]  is :"+mSections[i]);             mPositions[i] = position;             position += counts[i];         }         mCount = position;     }

传入的参数

String[] sections  : 是从数据库获取到的存在的首字母的数组。

int[] counts: 为每个首字母分组下的纪录条目。

 

    public int getPositionForSection(int section) {
        if (section < 0 || section >= mSections.length) {
            return -1;
        }

        return mPositions[section];
    }

    public int getSectionForPosition(int position) {
        if (position < 0 || position >= mCount) {
            return -1;
        }

        int index = Arrays.binarySearch(mPositions, position);

        /*
         * Consider this example: section positions are 0, 3, 5; the supplied
         * position is 4. The section corresponding to position 4 starts at
         * position 3, so the expected return value is 1. Binary search will not
         * find 4 in the array and thus will return -insertPosition-1, i.e. -3.
         * To get from that number to the expected value of 1 we need to negate
         * and subtract 2.
         */
        return index >= 0 ? index : -index - 2;
    }

mPositions 存储的是 每个sectionHeader 的开始位置。

如A:3个, B:2个 C:4个。那么其mPositions[0] =0 ,mPositions[1]=3, mPositions[2] = 5.

getSectionForPosition,通过你给出的位置去判断此条纪录属于哪个sectionHeader的。里面使用到得binarySearch说明:假设要查找的 position为4 ,那它应该是属于mPosition[1]的Header。 但是Binary search 它不会找到4这个数字,所以 在3 和5之间, 他需要返回:插入的-(insertPosition = 2)-1 的值也就是-3。 我们要转化为为我们需要获取的正确的section 的值 就应该使用 - index -2 得到。

 


 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值