热门标签 | 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%满足自己的要求,所以自己能看懂源码的话就可以自己去修改了。

源码下载在这里。

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


推荐阅读
  • 从零开始构建完整手机站:Vue CLI 3 实战指南(第一部分)
    本系列教程将引导您使用 Vue CLI 3 构建一个功能齐全的移动应用。我们将深入探讨项目中涉及的每一个知识点,并确保这些内容与实际工作中的需求紧密结合。 ... [详细]
  • 非公版RTX 3080显卡的革新与亮点
    本文深入探讨了图形显卡的进化历程,重点介绍了非公版RTX 3080显卡的技术特点和创新设计。 ... [详细]
  • 深入解析:手把手教你构建决策树算法
    本文详细介绍了机器学习中广泛应用的决策树算法,通过天气数据集的实例演示了ID3和CART算法的手动推导过程。文章长度约2000字,建议阅读时间5分钟。 ... [详细]
  • 本文作者分享了在阿里巴巴获得实习offer的经历,包括五轮面试的详细内容和经验总结。其中四轮为技术面试,一轮为HR面试,涵盖了大量的Java技术和项目实践经验。 ... [详细]
  • Python 工具推荐 | PyHubWeekly 第二十一期:提升命令行体验的五大工具
    本期 PyHubWeekly 为大家精选了 GitHub 上五个优秀的 Python 工具,涵盖金融数据可视化、终端美化、国际化支持、图像增强和远程 Shell 环境配置。欢迎关注并参与项目。 ... [详细]
  • 本文探讨了如何通过一系列技术手段提升Spring Boot项目的并发处理能力,解决生产环境中因慢请求导致的系统性能下降问题。 ... [详细]
  • 最新计算机专业原创毕业设计参考选题都有源码+数据库是近期作品ling取参考你的选题刚好在下面有,有时间看到机会给您发1ssm资源循环利用2springboot校园考勤系统3ssm防 ... [详细]
  • 深入解析JVM垃圾收集器
    本文基于《深入理解Java虚拟机:JVM高级特性与最佳实践》第二版,详细探讨了JVM中不同类型的垃圾收集器及其工作原理。通过介绍各种垃圾收集器的特性和应用场景,帮助读者更好地理解和优化JVM内存管理。 ... [详细]
  • 使用Numpy实现无外部库依赖的双线性插值图像缩放
    本文介绍如何仅使用Numpy库,通过双线性插值方法实现图像的高效缩放,避免了对OpenCV等图像处理库的依赖。文中详细解释了算法原理,并提供了完整的代码示例。 ... [详细]
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文介绍了如何使用PHP代码实现微信平台的媒体素材上传功能,详细解释了API接口的使用方法和注意事项,确保文件路径正确以避免常见的错误。 ... [详细]
  • 利用SSH隧道实现外网对局域网机器的安全访问
    本文探讨了一种常见的网络配置问题及其解决方案,即如何在外网环境下安全地访问位于局域网内的计算机。特别介绍了使用SSH反向隧道技术来实现这一目标的具体步骤和注意事项。 ... [详细]
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社区 版权所有