android仿微信联系人索引列表

Android 自定义View--SliderBar亮度icon动效 【代码】Android 自定义View--SliderBar亮度icon动效。 阅读详情

前言

  因为自己在做的一个小软件里面需要用到从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 < nAssortCount; i++){  
            mPaint.setAntiAlias(true);  // 抗锯齿   
            mPaint.setTypeface(Typeface.DEFAULT_BOLD);  // 默认粗体 
            mPaint.setColor(Color.parseColor("#5f5f5f"));  // 白色  
            if (i == mSelectIndex){  
                // 被选择的字母改变颜色和粗体  
                mPaint.setColor(Color.parseColor("#3399ff"));  
                mPaint.setFakeBoldText(true);  
                mPaint.setTextSize(30);  
            }  
            float xPos = hWidth / 2 - mPaint.measureText(ASSORT_TEXT[i]) / 2;  // 计算字母的X坐标  
            float yPos = nInterval * i + nInterval;  // 计算字母的Y坐标  
            canvas.drawText(ASSORT_TEXT[i], xPos, yPos, mPaint);  
            mPaint.reset();  
        }  
    }  

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        //判断是哪一个字母被点击了
        int nIndex = (int) (event.getY() / getHeight() * ASSORT_TEXT.length);
        if (nIndex >= 0 && nIndex < ASSORT_TEXT.length){
            switch (event.getAction()){  
            case MotionEvent.ACTION_MOVE:  
                // 如果滑动改变  
                if (mSelectIndex != nIndex){  
                    mSelectIndex = nIndex;
                    showCharacter(ASSORT_TEXT[mSelectIndex]);
                    if (mListener != null){
                        mListener.onTouchAssortListener(ASSORT_TEXT[mSelectIndex]);
                    }
                }  
                break;  
            case MotionEvent.ACTION_DOWN:  
                mSelectIndex = nIndex;  
                showCharacter(ASSORT_TEXT[mSelectIndex]);
                if (mListener != null){  
                    mListener.onTouchAssortListener(ASSORT_TEXT[mSelectIndex]);  
                }  

                break;  
            case MotionEvent.ACTION_UP:  
                disShowCharacter();
                mSelectIndex = -1;  
                break;  
            }  
        } else {  
            mSelectIndex = -1;  
            disShowCharacter();
        }  
        invalidate();
        return true;
    }

    private void disShowCharacter() {
        if (mPopupWindow != null) {
            mPopupWindow.dismiss();
            mPopupWindow=null;
        }
    }

    /**
     * 显示弹出的字符
     * @param string
     */
    private void showCharacter(String string){

        if (mPopupWindow != null){
            text.setText(string);
        } else{   
            mPopupWindow = new PopupWindow(layoutView, 100, 100, false);
            mPopupWindow.showAtLocation(mAttachActivity.getWindow().getDecorView(), Gravity.CENTER, 0, 0);
        }
        text.setText(string);
    }
}  

  就先看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<DataBean>{
    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<DataBean> list){
        List<DataBean> _List = new ArrayList<DataBean>();
        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.size();i++){
            if(getFirstCharacter(list.get(i).getItem_en()).compareTo(currentCharacter)!=0){
                currentCharacter = getFirstCharacter(list.get(i).getItem_en());
                dataBean = new DataBean(currentCharacter, "",DataBean.TYPE_CHARACTER);
                _List.add(dataBean);
            }
            _List.add(list.get(i));
        }
        list.clear();
        for(DataBean bean:_List){
            list.add(bean);
        }
    }
    public static String getFirstCharacter(String str){
        return str.substring(0, 1);
    }
}

  这个类就实现了往List对象里面添加一些表示字母分隔符的对象,通过设置item_type变量的值不同,在Adapter里面根据这个值返回不同的View就可以实现不同的Item显示。
  好了,到现在只剩一个问题了,那就是点击了字母之后,ListView设置该字母对应的Item在第一个显示,这个实现也不难,得到了被点中的字母之后,遍历所有的DataBean对象,然后找到和当前字母匹配的第一个字母分隔符对象,然后得到该Item的position的值,设置ListView被选中的Item的position为找到的Item的position即可。
  终于,所有的问题解决了,看看现在自己能不能实现这样的效果了呢?如果不行的话可以参考一个我的源码。

小结

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

【源码下载】

android 仿微信demo————微信通讯录界面功能实现(移动端,服务端) 以往文章 android 仿微信demo————微信启动页实现 android 仿微信demo————注册功能实现(移动端) android 仿微信demo————注册功能实现(服务端) android 仿微信demo————登录功能实现(移动端) android 仿微信demo————登录功能实现(服务端) android 仿微信demo————微信主界面实现 android 仿微信demo————微信消息界面实现(移动端) android 仿微信demo————微信消息界面实现(服务端) 前面我们实现 阅读详情

相关推荐

仿微信安卓应用开发实战项目(Android Studio)

随着移动互联网的深入发展,即时通讯类应用已成为Android开发技术集大成者。微信作为国民级应用,其简洁流畅的UI交互、高效的消息机制与模块化架构设计,为开发者提供了极佳的学习范本。通过仿写微信客户端,不仅能系统掌握Android核心组件的实际应用,更能深入理解高耦合场景下的工程解耦思想。是 Material Design 提供的标准组件,专用于实现底部标签导航。其核心配置包括菜单资源引用、图标与文字样式设定等。首先,在中定义菜单项:<itemandroid:title="聊天"

weixin_42513870的博客 1477

Android 快速实现 仿微信通讯录

Android 快速实现 微信通讯录 Androidx

一只小翊的博客 1500

Android代码-SlideBar

SlideBar SlideBar for Android 一个很好用的联系人快速索引。 Gif 展示 引入 Maven: com.king.view slidebar 1.1.0 pom Gradle: compile 'com.king.view:slidebar:1.1.0' Lvy: 如果Gradle出现compile失败的情况,可以在Project的build.gradle里面添加如下:(也可以使用上面的GitPack来complie) allprojects { repositories { maven { url 'https://dl.bintray.com/jenly/maven' } } } 具体实现详情请戳传送门 关于我 Name: Jenly Email: jenly1314@gmail.com / jenly1314@vip.qq.com 优快云: http://blog.youkuaiyun.com/jenly121 Github: https://github.com/jenly1314 微信公众号

Android仿微信自定义字母导航栏

自定义侧边字母导航栏,根据实际字母高度进行显示 先上效果图 导航栏 气泡 1.自定义view实现 public class SlideBar extends View { public static final String TAG = SlideBar.class.getSimpleName...

Tanyjinlong的博客 521

android仿微信通讯录搜索示例(匹配拼音,字母,索引位置)

前言: 仿微信通讯录搜索功能,通过汉字或拼音首字母找到匹配的联系人并显示匹配的位置 一:先看效果图 字母索引 搜索匹配 二:功能分析 1:汉字转拼音 通讯录汉字转拼音(首个字符当考虑姓氏多音字), 现在转换拼音常见的有pinyin4j和tinypinyin, pinyin4j的功能强大,包含声调多音字,tinypinyin执行快占用内存少, 如果只是简单匹配通讯录,建议使用tinypinyin,用法也很简单这里不详细介绍 拼音类 public class CNPinyin implements Serializable, Comparable<CNPi

Android实现仿通讯录侧边栏滑动SiderBar效果代码

主要介绍了Android实现仿通讯录侧边栏滑动SiderBar效果代码,实例分析了通讯录侧边栏滑动效果的实现技巧,并附带完整实例代码供读者下载参考,需要的朋友可以参考下

android 联系人 字母索引,Android ListView字母索引(仿微信通訊錄列表)

布局代碼xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent" >android:id="@+id/letterListView"android:layout_width="match_parent"android...

weixin_30959465的博客 311

ECU-TEST笔记&使用技巧01

说明 1)所述均基于如下环境:ECU-TEST 8.0、Win10系统、NI Veristand 2018(HIL测试)。不排除因为版本及软件环境问题,所述方法不奏效或有更好的方法,欢迎交流,一起提高。 2)本博客以问答形式进行,所述问题均来自于实际测试(包括MIL、HIL测试)遇到的问题及需求,目的是提高测试效率和自动化测试序列的可维护性。 3)本博客尽量从测试方法及ECU-TEST原...

Eigrl的博客 1万+

android 通讯录界面设计带字母,android仿微信联系人索引列表功能

前言因为自己在做的一个小软件里面需要用到从A-Z排序的ListView,所以自然而然的想到了微信的联系人,我想要的就是那样的效果。本来没打算自己去写,想要第三方写好的东西,搜了几个之后发现有的太复杂了,有的简单是简单,但是不符合我的要求,所以我就来个整合,把复杂性和简单性合二为一。实现先来看效果图吧:要点分析要实现这样的效果需要考虑下面的几个问题:右边字母栏的绘制点击效果的实现汉字按A-Z的排序问...

weixin_31613423的博客 998

Unity类银河战士恶魔城学习总结(P162 Improve skeleton提升敌人的效果)

为敌人添加了快慢刀

suzh1qian的博客 572

【顾邦小讲堂】第二十四期 电源环路测试从入门到精髓:一文掌握环路测试原理与电压注入点选择依据

电源环路测试是评估开关电源、线性电源等闭环系统稳定性的核心手段,直接关系到电源的稳定性、输出精度、动态响应、抗干扰能力甚至可靠性

GBupupup的博客 2116

android仿微信点击好友,安卓仿微信联系人快速索引

importandroid.content.Context;importandroid.graphics.Canvas;importandroid.graphics.Paint;importandroid.support.annotation.Nullable;importandroid.util.AttributeSet;importandroid.view.MotionEvent;import...

weixin_39993454的博客 200

transformer中QKV的通俗理解(剩女与备胎的故事)

用vit的时候读了一下transformer的思想,前几天面试结束之后发现对QKV又有点忘记了, 写一篇文章来记录一下 参考链接: 哔哩哔哩:在线激情讲解transformer&Attention注意力机制(上)在线激情讲解transformer&Attention注意力机制(上)_哔哩哔哩_bilibiliAttention is all you need介绍 更具体的介绍可以去阅读论文在Attention is all you need这篇文章中提出了著名的Transformer模型Transforme

Peter的博客 1万+

Android 仿联系人字母索引

Android 仿联系人滚动至字母索引

weishl110的博客 554

gmsv源代码c语言,石器时代ABLua的原理、简介、过程、运用、收发

操作原理(一)服务端:服务器源文件客户端:客户所操作的程序(既是游戏客户端)接口:既是某项功能(例如:鼠标点击,文字发送,战斗,观战,人物动作等)返回的值ABlua:在源代码中添加的整套引擎作为回调接口--lua所实现的功能是基于服务端源码添加的接口由该接口与客户端发送封包实现功能源码里是否有ABlua回调接口?例如:源码里的gmsv/battle.c文件(既是战斗回调文件)以下为简单描述C给予l...

weixin_35223575的博客 2408

AI 实战篇 |基于 AI开放平台实现 人脸识别对比 功能,超详细教程【附带源码】

本篇文章来学习一下怎样使用 Unity实现简单地人脸识别 功能。 关于人脸识别,我们可以选择很多平台的SDK接入Unity来实现人脸识别的功能。

努力前行,总会成为自己心中的那道光 5万+

带中文索引的ListView 仿微信联系人列表

因为各种原因,项目经理和产品经理把我做的东西给否定了,所以决定分享出去。 主要功能: 1 、带中文索引的ListView 2、自己定义顶部搜索视图,能够对返回button,搜索button加入事件监听,带动画的咧!~ 3、底部自己定义视图,能够对Listview的adapter加入监听,而且回调选中的数目,另外其它的视图都是能够自己加入的 4、右側的索引视图,依据通讯录的...

weixin_33730836的博客 181

真题库系列之 CCF GESP 2025年12月认证 Python 1级真题含正确答案与解析

学生通过计算机基础知识的学习,了解计算机的构成与操作,以及计算机的发 展历程。通过编程基础知识以及语句的掌握,可以独立完成简单功能的顺序结构、 分支结构、循环结构的程序。

iCloudEnd的博客 318

Android仿微信通讯录功能,好友排序+字母索引

一、效果图展示 二、功能特点 1.好友排序:按照拼音顺序对好友进行排序,兼容英文数字符号等 2.字母索引:右侧字母导航条,既可拖动也可点击,联动ListView滑动 三、实现 接下来就让我们一步步显示这个效果吧。 1.右侧字母索引的导航条 这个我们可以在网上找到很多类似的,你大可找一个自己喜欢的甚至自己写一个出来,这里我在网上找了一个带波浪效果的,看起来比较炫酷一点吧。

YZJ_0722的博客 723

CelebA-HQ数据集下载【详细明了版】分辨率包括【64,128,256,512,1024】

CelebA-HQ 是在ICLR2018上,nVidia发表了一篇名为Progressive Growing of GANs for Improved Quality, Stability, and Variation的论文,文中通过训练高分辨率GAN生成了一个新的人脸数据集CelebA-HQ.CelebA是港科大汤晓鸥组收集的人脸数据集(总共200k图片),包括了人脸特征点(landmark),人脸属性(attribute)等信息,详细介绍参考链接[1]和[2]

zik的博客 1万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Android仿微信添加联系人列表,内附有截图和demo源码

分享一个Android仿微信选择联系人页面 之前做的App主要是工具类的,而且公司的产品经理也喜欢在App里设计很多自定义控件,所以比一般市场上的App要麻烦一些,今天先介绍一个仿微信选择联系人的页面,涉及的功能较多 页面实现了哪些功能 将联系人名字首字母进行a-z排序,并且每一个字母都有一个头部,没有获取首字母的则放入#分类中,并且在a前面加入一个常用联系人展示 在列表右边有一列从 常、a-z...

y1010012836的博客 1万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

仿微信通讯录如何得到侧栏索引的搜索字符

1.首先很明显直接打搜索是这个

georgehenrywilliam的博客 1067

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

浅谈android中手机联系人字母索引表的实现

实际上字母索引表的效果,可以说在现在的众多APP中使用的非常流行,比如支付宝,微信中的联系人,还有购物,买票的APP中选择全国城市,切换城市的时候,这时候的城市也就是按照一个字母索引的顺序来显示,看起来是很方便的.其实这种字母索引表的效果最开始是出现在微信的联系人中.因为觉得这种效果功能在今后的项目中可以说是非常常见,可能会用的上,所以准备来波博客讲述一下实现的原理,一来方便以后自己复习,二来如果

Mikyou的专栏 1万+

Android 通过ListView实现联系人列表字母索引

转载:https://blog.youkuaiyun.com/a_zhon/article/details/53214849 学习大神的思路和逻辑,很清晰。 这篇博文也不错:https://blog.youkuaiyun.com/iamdingruihaha/article/details/61921010 相信大家对这个列表字母索引已经不陌生了,在很多app中也随处可见,像没团的城市地址选择,微信联系人列表,手机...

残风乱了温柔的博客 4715

仿微信联系人列表滑动字母索引

今天做到了一个联系人列表的需求, 要求和微信的一样! 写出来分享给大家, 使用了jq和doT模版引擎(doT模版教程) 预览页面地址首先对数据源进行数据排序 // 数据排序 function sortData(data) { var letterArr = []; for (var i = 0; i < data.length; i++) {

Mr.Yuan 8055
上一篇: 我的优快云博客阅读器完成啦!!
下一篇: Collections结合Comparator实现对列表的快速排序
潘建成
博客等级 码龄12年 139粉丝 120原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值