热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

android仿微信联系人索引列表功能

这篇文章主要为大家详细介绍了android仿微信联系人索引列表功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

前言

  因为自己在做的一个小软件里面需要用到从A-Z排序的ListView,所以自然而然的想到了微信的联系人,我想要的就是那样的效果。本来没打算自己去写,想要第三方写好的东西,搜了几个之后发现有的太复杂了,有的简单是简单,但是不符合我的要求,所以我就来个整合,把复杂性和简单性合二为一。

实现

  先来看效果图吧:

要点分析

  要实现这样的效果需要考虑下面的几个问题:

  • 右边字母栏的绘制
  • 点击效果的实现
  • 汉字按A-Z的排序问题
  • 正常的Item和字母分隔符的Item的实现

  下面我们就解决这几个问题,然后就可以出现上面的效果了。

【第一步】

  我们需要先自定义一个类,就叫SlideBar吧,让它继承Button,然后我们覆盖onDraw方法,绘制字母a-z就可以出现右边字母栏的效果了。

看一下源码:

public class SlideBar extends Button{ 

 public interface OnTouchAssortListener{ 
 public void onTouchAssortListener(String s); 
 } 

 // 分类 
 private static final String[] ASSORT_TEXT = {"A", "B", "C", "D", "E", "F", "G", 
 "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", 
 "U", "V", "W", "X", "Y", "Z" ,"#"};

 private Paint mPaint = new Paint(); 
 private int mSelectIndex = -1; 
 private OnTouchAssortListener mListener = null;
 private Activity mAttachActivity;
 PopupWindow mPopupWindow = null;
 View layoutView;
 TextView text;

 public SlideBar(Context context){ 
 this(context,null); 
 } 

 public SlideBar(Context context, AttributeSet attrs) { 
 this(context, attrs,0); 
 } 

 public SlideBar(Context context, AttributeSet attrs, int defStyle){ 
 super(context, attrs, defStyle);
 mAttachActivity = (Activity)context;
 init(context);
 } 
 private void init(Context context) {
 layoutView = LayoutInflater.from(context).inflate(R.layout.alert_dialog_menu_layout, null);
 text = (TextView) layoutView.findViewById(R.id.content);
 }

 public void setOnTouchAssortListener(OnTouchAssortListener listener) {
 this.mListener = listener;
 }

 @Override 
 protected void onDraw(Canvas canvas){ 
 super.onDraw(canvas);
 int nHeight = getHeight(); 
 int hWidth = getWidth(); 
 int nAssortCount = ASSORT_TEXT.length;
 int nInterval = nHeight / nAssortCount;

 for (int i = 0; i = 0 && nIndex 

  就先看onDraw方法,其他的内容先不看,首先得到控件的宽和高,然后计算每一个字母应该占据的高度为多少,然后在每一个字母所占空间的中间绘制该字母就可以了,代码比较简单,这一部分就不需要详解了。

【第二步】

  我们需要添加一个点击事件,当点击SlideBar的时候,首先可以看到的是右边栏被点击的字母变大来区别于没被点击的字母,然后弹出一个类似Dialog的东西,显示被点中的字母,这个效果也很好实现。
  在SlideBar里面我们还需要覆盖的一个方法是dispatchTouchEvent(),我们点中SlideBar之后,接下来的动作可能是滑动和抬起,我们需要对点击之后的动作进行响应,如果是抬起的话,那么显示出来的类似dialog的东西就要消失,变大的字母也要回复原样,如果是接着滑动,滑到某一个字母的时候,对应的字母就要变大和显示出来。
  从上面的源码可以看到,字母变大的效果很好实现,把绘制被选中的字母的Paint对象的textsize的值变大就可以了,然后那个类似dialog的东西是用PopupWindow来实现的,当点击和滑动的时候就显示PopupWindow,抬起或者滑出SlideBar范围的时候就让PopupWindow消失。最后需要注意的是invalidate()这个方法千万不要忘记调用了,这个是用来进行画面的重绘。

【第三步】

  我认为最重要也是最难的就是汉字按A-Z的排序了。不过还好,这个已经有人实现了,我们就来所谓的“拿来主义”吧。在工程里面有一个CharacterParser类,这个类封装了对汉字转拼音的操作,其中getSelling(String s)方法的作用是传入汉字字符串得到汉字的拼音,果然是好方法,我喜欢!!这样我们就得到了要显示的汉字字符串的拼音首字母,然后将所有的字符串按照字母进行排序就可以得到一个从A-Z的有序的列表了。因为ListView一般都是绑定一个List对象,然后List对象里面保存一系列的对象,这里我就用一个对象来说:

public class DataBean {

 public static final int TYPE_CHARACTER = 0;
 public static final int TYPE_DATA = 1;
 private int item_type;
 private String item_en;
 private String name;
 private String phone;
 /*其他成员*/

 public DataBean(String name,String phone,int type){
 CharacterParser parser = CharacterParser.getInstance();
 this.name = name;
 this.phOne= phone;
 this.item_type = type;
 this.item_en = parser.getSelling(name).toUpperCase().trim();
 if(!item_en.matches("[A-Z]+")){
 item_en = "#"+item_en;
 }
 }

 /*
 *省略geter和seter方法 
 */
}

  这个对象里面需要注意的是两个成员变量,item_type和item_en,分别表示该对象是要显示的正常对象还是字母分隔符对象,根据item_type的不同,我们在写Adapter的getView方法的时候就可以返回不同的View对象,然后就可以实现效果图中的正常的Item和字母分割符Item了。item_en表示的是name变量也就是汉字字符串的拼音字符串,主要是用来获取首字母和进行字符串之间的比较。

  现在假设已经有了一个List对象,里面保存了一些DataBean,那么问题来了,如何把这些DataBean对象按拼音字符串进行排序以及如何在List对象里面添加表示字母分隔符的DataBean对象呢?

首先解决排序的问题,这个比较简单:

  这里用到了Collections的sort方法,这个方法有两个参数,一个就是带排序的List对象,另一个是实现了Comparator接口的类的对象,用来说明如何进行排序,用哪一个成员变量来进行排序。

  PinyinComparator这个类实现了Comparator:

public class PinyinComparator implements Comparator{
 public int compare(DataBean o1, DataBean o2){
 if (o1.getItem_en().equals("@")
 || o2.getItem_en().equals("#")){
 return -1;
 } else if (o1.getItem_en().equals("#")
 || o2.getItem_en().equals("@")) {
 return 1;
 } else {
 return o1.getItem_en().compareTo(o2.getItem_en());
 }
 }
}

  可以看到,两个DataBean对象按照变量item_en也就是拼音字符串来进行排序,这样实现起来比较方便,不需要自己去写排序的算法了,当然也不反对大家自己去实现排序。

  经过Collections的sort函数排序之后,现在List对象里面保存的DataBean对象已经是按照A-Z进行排序的了,现在我们要做的就是在这些对象里面插入一些用来表示字母分隔符DataBean的对象,这个实现应该比较简单,我用的方法比较笨/(ㄒoㄒ)/~~

public class ListUtil {
 public static void sortList(List list){
 List _List = new ArrayList();
 Collections.sort(list, new PinyinComparator());
 DataBean dataBean = new DataBean(getFirstCharacter(list.get(0).getItem_en()), "",DataBean.TYPE_CHARACTER);
 String currentCharacter = getFirstCharacter(list.get(0).getItem_en());
 _List.add(dataBean);
 _List.add(list.get(0));
 for(int i=1;i

  这个类就实现了往List对象里面添加一些表示字母分隔符的对象,通过设置item_type变量的值不同,在Adapter里面根据这个值返回不同的View就可以实现不同的Item显示。

  好了,到现在只剩一个问题了,那就是点击了字母之后,ListView设置该字母对应的Item在第一个显示,这个实现也不难,得到了被点中的字母之后,遍历所有的DataBean对象,然后找到和当前字母匹配的第一个字母分隔符对象,然后得到该Item的position的值,设置ListView被选中的Item的position为找到的Item的position即可。

  终于,所有的问题解决了,看看现在自己能不能实现这样的效果了呢?如果不行的话可以参考一个我的源码。

小结

  本来我也是对这个不是太懂,但是强迫自己去看源码,因为网上的大神写的东西可能并不是100%满足自己的要求,所以自己能看懂源码的话就可以自己去修改了。

源码下载在这里。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 近年来,大数据成为互联网世界的新宠儿,被列入阿里巴巴、谷歌等公司的战略规划中,也在政府报告中频繁提及。据《大数据人才报告》显示,目前全国大数据人才仅46万,未来3-5年将出现高达150万的人才缺口。根据领英报告,数据剖析人才供应指数最低,且跳槽速度最快。中国商业结合会数据剖析专业委员会统计显示,未来中国基础性数据剖析人才缺口将高达1400万。目前BAT企业中,60%以上的招聘职位都是针对大数据人才的。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 小程序获取用户信息按钮返回中文地址
    1.我是根据官方文档中描述去写的按钮 可以看到button中加了zh_CNopen-typegetUserInfobindgetuserinfogetU ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
  • 现在比较流行使用静态网站生成器来搭建网站,博客产品着陆页微信转发页面等。但每次都需要对服务器进行配置,也是一个重复但繁琐的工作。使用DockerWeb,只需5分钟就能搭建一个基于D ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • 本文详细解析了JavaScript中相称性推断的知识点,包括严厉相称和宽松相称的区别,以及范例转换的规则。针对不同类型的范例值,如差别范例值、统一类的原始范例值和统一类的复合范例值,都给出了具体的比较方法。对于宽松相称的情况,也解释了原始范例值和对象之间的比较规则。通过本文的学习,读者可以更好地理解JavaScript中相称性推断的概念和应用。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
author-avatar
小菜鸡
新手
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有