最近闲的很,没什么事干 ,在玩手机的时间看到android系统自带的那个通讯录软件对联系人的快速定位功能.  感觉这个功能也比较实用自己就试着自己去实现.

虽然网络上还是有大牛封闭好了的框架,但是如果自己来实现一下也是不错的, 个人比较喜欢自己写的东西,别人写好的东西可以拿来借鉴,还是不推荐看也不看直接拿

来用,代码可以复制,作者的思想就需要慢慢体会的.

基本介绍:

   首先安卓本身已经提供一个接口来实现快速定位的, SectionIndexer接口共有三个方法.

   

    Object[] getSections();              //返回所有的section

    

    int getPositionForSection(int sectionIndex);    //根据section索引返回一个position

   int getSectionForPosition(int position);      //与上面的方法正好相反 .

   section可以理解为一个ListView中的一部分,比如在联系人进行分组将首字母相同的分为同一组,每一组就是一个section.

基本设计:

  我将那些字母的列表看成是一个View这个View里面包含一个实现SectionIndexer接口的成员. 且定义一个回调接口用于在索引更改时通知更新ListView.

  重写onMeasure(int,int)方法计算View的宽高.

  

	@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if(mSectionIndex == null){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return ;
} if(mSections == null)
mSections = mSectionIndex.getSections(); int measureHeight ;
int measureWidth ;
int height = (int) (sectionHeight() * mSections.length ) + ( getPaddingTop() + getPaddingBottom() );
int width = sectionWidth() + getPaddingLeft() + getPaddingRight(); /**
* 根据布局参数来设置View的宽高.
* 如果布局参数的高或宽为LayoutParams.WRAP_CONTENT
* 则View的宽高分别为 width , height
* 否则直接根据布局参数的数值来设置
*/
LayoutParams lp = getLayoutParams();
if(lp.height != LayoutParams.WRAP_CONTENT)
height = lp.height; if(lp.width != LayoutParams.WRAP_CONTENT)
width = lp.width; /** */
measureHeight = ViewGroup.getChildMeasureSpec(heightMeasureSpec, 0,height);
measureWidth = ViewGroup.getChildMeasureSpec(widthMeasureSpec, 0, width); setMeasuredDimension(measureWidth, measureHeight);
}

重写onLayout方法,重写该方法的原因是使所有的索引填满View. 不一定要重写onLayout方法,只要在View能够得到高度后再计算就可以.

@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
/**
* view 的高度大于列表显示的高度, 在每一个字母之间加入一些间隔,
* 使每一个字母对齐,并填满整个view.
*/
int viewHeight = getHeight() - (getPaddingTop() + getPaddingBottom());
int originalHeight = mHeight * mSections.length; int overHeight = viewHeight - originalHeight; if(overHeight <= 0) return ; mAlphaInterval = overHeight / (mSections.length);
}

重写onDraw方法,这个方法就不用多说了吧,大家都知道是干什么的,直接上代码.

	@Override
protected void onDraw(Canvas canvas) { if(mSectionIndex == null)
return ; int height = getHeight();
int widht = getWidth();
//画背景
if(mBackground){
RectF round = new RectF(0, 0, widht, height);
canvas.drawRect(round, mBackgroundPaint);
} //画字母
float textheight = mAlphaPaint.descent()- mAlphaPaint.ascent();
float y = textheight / 1.5f + getPaddingTop(); //第一个字母偏移 .
float x = getPaddingLeft() ;
for(int i = 0; i < mSections.length ; i++){ if(mCurrentSection == i)
mAlphaPaint.setColor(Color.BLUE);
else
mAlphaPaint.setColor(Color.WHITE); y += mAlphaPadding + mAlphaInterval;
canvas.drawText(mSections[i].toString() , x, y, mAlphaPaint);
y += mAlphaPadding + textheight ;
} }

效果图:

  

最后还包含一些辅助方法,就不一一例举的大家下载源码一看便知.

源码下载 :

  http://pan.baidu.com/s/1gdw1gyf

android字母索引实现ListView定位的更多相关文章

  1. 做个简单的Android列表字母索引控件

    相信大家在许多App中都见到过带字母索引的界面,比如我最近看到的这个开源控件: WaveSideBar 很酷是不是?!!!如果加在例如联系人列表界面上,大大提升了用户体验. 那么这个索引控件要怎么做呢 ...

  2. 老猪带你玩转android自定义控件二——自定义索引栏listview

    带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样: 今天,我们就从零到一实现这个具有索引栏的listview. 怎么实现这个控件了,我们应当梳理出一个 ...

  3. 玩转android自定义控件二——自定义索引栏listview

    带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样: 今天,我们就从零到一实现这个具有索引栏的listview. 怎么实现这个控件了,我们应当梳理出一个 ...

  4. 联系人的侧边字母索引ListView 将手机通讯录姓名通过首字母排序。

      package com.lixu.letterlistview; import java.util.ArrayList; import java.util.List; import org.apa ...

  5. android之listView定位到指定行同时隐藏输入键盘

    帮别人该bug遇到的一个问题,记录下来. listView.setSelection(a); 这个方法可以让让你的listview定位到指定行 但是如果紧接着执行隐藏输入键盘的代码,则会有bug,这个 ...

  6. android之listView定位到指定行同一时候隐藏输入键盘

    帮别人该bug遇到的一个问题,记录下来. listView.setSelection(a); 这种方法能够让让你的listview定位到指定行 可是假设紧接着运行隐藏输入键盘的代码.则会有bug.这个 ...

  7. 8.快速索引、listview

    实现这样的效果 布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ...

  8. Android带索引联系人列表

    网上Android联系人列表的样例也非常多,都和微信的联系人差点儿相同,因为项目用到了联系人列表索引功能(产品把字母item给去掉了),只是也还是好实现.这里我也来分享分享我的实现,免得以后忘了.那先 ...

  9. Android中动态更新ListView(转)

    在使用ListView时,会遇到当ListView列表滑动到最底端时,添加新的列表项的问题,本文通过代码演示如何动态的添加新的列表项到ListView中.实现步骤:调用ListView的setOnSc ...

随机推荐

  1. Leetcode之二分法专题-367. 有效的完全平方数(Valid Perfect Square)

    Leetcode之二分法专题-367. 有效的完全平方数(Valid Perfect Square) 给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 ...

  2. Delphi - 使用Pos、Copy函数定位和截取字符串

    使用Pos函数来定位子字符串第一次出现的位置 函数定义: Function Pos(Substr: String, S: String): Integer; 表示取出Substr在S中第一次出现的位置 ...

  3. codeforces 816 E. Karen and Supermarket(树形dp)

    题目链接:http://codeforces.com/contest/816/problem/E 题意:有n件商品,每件有价格ci,优惠券di,对于i>=2,使用di的条件为:xi的优惠券需要被 ...

  4. Covered Points Count CF1000C 思维 前缀和 贪心

     Covered Points Count time limit per test 3 seconds memory limit per test 256 megabytes input standa ...

  5. yzoj P2344 斯卡布罗集市 题解

    共t条街对于每一条街上有n个店铺(n可能不相同),每次只能选两端第一个营业的店铺采购,采购第i个店铺会获得幸福度ai,采购完后,这个店铺和它相邻的店铺便会关门,问最大幸福度? 考场想了一下dp,一开始 ...

  6. 最小生成树问题---Prim算法学习

    一个具有n个节点的连通图的生成树是原图的最小连通子集,它包含了n个节点和n-1条边.若砍去任一条边,则生成树变为非连通图:若增加一条边,则在图中形成一条回路.本文所写的是一个带权的无向连通图中寻求各边 ...

  7. 【Ehcache】基础知识学习

    一.Ehcache概述 1.1 简介 1.2 Ehcache的主要特性 二.Ehcache使用介绍 2.1 Ehcache缓存过期策略 2.2 如何解决缓存与db不同步的问题. 三.Ehcache 基 ...

  8. 基于STM32F429的TFT0.96屏幕驱动

    1.介绍TFT 2.Cube配置  该屏幕是用SPI通信的,但没有MISO引脚,意思是说该屏幕只能接收数据,但无法读取里面的数据,理论上说四线就能启动,但我弄不出,只能用六线. 在Cube上只要开启六 ...

  9. 阿里社招Java面试题总结——面试官分享

    面试题 1.Java中的内存溢出是如何造成的 2.gc的概念,如果A和B对象循环引用,是否可以被GC? 3.Error.Exception和RuntimeException的区别,作用又是什么? 4. ...

  10. Go操作kafka

    Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据,具有高性能.持久化.多副本备份.横向扩展等特点.本文介绍了如何使用Go语言发送和接收kafka消息. s ...