Android仿微信通讯录

分3部:

1、listview实现显示头像、名字(太简单,这里就不写了)

通讯录页面xml布局代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><FrameLayoutandroid:id="@+id/fl"android:layout_width="match_parent"android:layout_height="wrap_content"><ListViewandroid:id="@+id/school_friend_member"android:layout_width="match_parent"android:layout_height="match_parent"android:cacheColorHint="@android:color/transparent"android:dividerHeight="1px"android:fadingEdge="none"android:listSelector="@android:color/transparent"android:scrollbars="none"></ListView><TextViewandroid:id="@+id/school_friend_dialog"android:layout_width="80dp"android:layout_height="80dp"android:layout_gravity="center"android:background="@color/green_light"android:gravity="center"android:textColor="#ffffffff"android:textSize="30dp"android:visibility="invisible" /><com.diancanwang.dell.diancanwang.chat.bean.SideBarandroid:id="@+id/school_friend_sidrbar"android:layout_width="30dp"android:layout_height="match_parent"android:layout_gravity="right|center" /></FrameLayout></LinearLayout>

2、实现A——Z的好友分类

首先 导入拼音依赖

compile files('libs/pinyin4j-2.5.0.jar')  (依赖可以到网上搜索一个,添加到app下面的libs文件夹里,我这里给出的是我添加好后app build.gradle里面的)

其次

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;import java.util.Comparator;/*** 2018/4/22.*/public class PinyinComparator implements Comparator<SortModel> {public int compare(SortModel o1, SortModel o2) {if (o1.getSortLetters().equals("@")|| o2.getSortLetters().equals("#")) {return -1;} else if (o1.getSortLetters().equals("#")|| o2.getSortLetters().equals("@")) {return 1;} else {return o1.getSortLetters().compareTo(o2.getSortLetters());}}public static String getPingYin(String inputString) {HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();format.setCaseType(HanyuPinyinCaseType.LOWERCASE);format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);format.setVCharType(HanyuPinyinVCharType.WITH_V);char[] input = inputString.trim().toCharArray();String output = "";try {for (char curchar : input) {if (java.lang.Character.toString(curchar).matches("[\u4e00-\u9fa5]+")) {String[] temp = PinyinHelper.toHanyuPinyinStringArray(curchar, format);output += temp[0];} elseoutput += java.lang.Character.toString(curchar);}} catch (BadHanyuPinyinOutputFormatCombination e) {e.printStackTrace();}return output;}}

实体类

/***  2018/4/22.* 实体类*/public class SortModel {private int img;//头像private String name;   //显示的数据private String sortLetters;  //显示数据拼音的首字母public SortModel(int img, String name, String sortLetters) {this.img = img;this.name = name;this.sortLetters = sortLetters;}public SortModel() {}public int getImg() {return img;}public void setImg(int img) {this.img = img;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSortLetters() {return sortLetters;}public void setSortLetters(String sortLetters) {this.sortLetters = sortLetters;}@Overridepublic String toString() {return "SortModel{" +"img=" + img +", name='" + name + '\'' +", sortLetters='" + sortLetters + '\'' +'}';}
}
import android.widget.ListView;
import android.widget.TextView;import com.diancanwang.dell.diancanwang.R;
import com.diancanwang.dell.diancanwang.base.BaseFragment;
import com.diancanwang.dell.diancanwang.chat.adapter.SortAdapter;
import com.diancanwang.dell.diancanwang.chat.bean.PinyinComparator;
import com.diancanwang.dell.diancanwang.chat.bean.SideBar;
import com.diancanwang.dell.diancanwang.chat.bean.SortModel;import java.util.ArrayList;
import java.util.List;import butterknife.Bind;/*** 通讯录页面*/
public class AddBookFragment extends BaseFragment {@Bind(R.id.school_friend_member)ListView mListView;@Bind(R.id.school_friend_dialog)TextView mDialog;@Bind(R.id.school_friend_sidrbar)SideBar mSideBar;private List<SortModel> list;@Overrideprotected int getLayoutId() {return R.layout.fragment_add_book;}@Overrideprotected void initView() {}@Overrideprotected void initData() {list = new ArrayList<>();
//        for (int i = 0; i < 10; i++) {SortModel sortModel = new SortModel();SortModel sortModel1 = new SortModel();SortModel sortModel2 = new SortModel();SortModel sortModel3 = new SortModel();SortModel sortModel4 = new SortModel();SortModel sortModel5 = new SortModel();sortModel.setImg(R.mipmap.ic_launcher);sortModel1.setImg(R.mipmap.ic_launcher);sortModel2.setImg(R.mipmap.ic_launcher);sortModel3.setImg(R.mipmap.ic_launcher);sortModel4.setImg(R.mipmap.ic_launcher);sortModel5.setImg(R.mipmap.ic_launcher);sortModel2.setName("华为");sortModel.setName("阿里巴巴");sortModel1.setName("百度");sortModel3.setName("xiaoxue");sortModel4.setName("……%¥#¥%#");sortModel5.setName("百家姓");String pingYin = PinyinComparator.getPingYin("阿里巴巴");String pingYin1 = PinyinComparator.getPingYin("百度");String pingYin2 = PinyinComparator.getPingYin("华为");String pingYin3 = PinyinComparator.getPingYin("xiaoxue");String pingYin4 = PinyinComparator.getPingYin("……%¥#¥%#");String pingYin5 = PinyinComparator.getPingYin("百家姓");sortModel3.setSortLetters(pingYin3);sortModel.setSortLetters(pingYin);sortModel1.setSortLetters(pingYin1);sortModel2.setSortLetters(pingYin2);sortModel4.setSortLetters(pingYin4);sortModel5.setSortLetters(pingYin5);list.add(sortModel2);list.add(sortModel1);list.add(sortModel3);list.add(sortModel);list.add(sortModel4);list.add(sortModel5);//        }}@Overrideprotected void initAdapter() {SortAdapter adapter = new SortAdapter(list, getActivity());mListView.setAdapter(adapter);}}

适配器

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.SectionIndexer;
import android.widget.TextView;import com.bumptech.glide.Glide;
import com.diancanwang.dell.diancanwang.R;
import com.diancanwang.dell.diancanwang.chat.bean.PinyinComparator;
import com.diancanwang.dell.diancanwang.chat.bean.SortModel;import java.util.Collections;
import java.util.List;/*** 2018/4/22.*/public class SortAdapter extends BaseAdapter implements SectionIndexer {private List<SortModel> list;private Context mContext;public SortAdapter(List<SortModel> list, Context mContext) {this.list = list;this.mContext = mContext;}public void updateListView(List<SortModel> list) {this.list = list;notifyDataSetChanged();}@Overridepublic int getCount() {return list.size();}@Overridepublic Object getItem(int position) {return list.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder = null;if (convertView == null) {viewHolder = new ViewHolder();convertView = LayoutInflater.from(mContext).inflate(R.layout.item, null);//头像viewHolder.imgHead = (ImageView) convertView.findViewById(R.id.book_head);//昵称viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.book_name);//索引字母viewHolder.tvLetter = (TextView) convertView.findViewById(R.id.catalog);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}获取首字母的assii值int section = getSectionForPosition(position);//通过首字母的assii值来判断是否显示字母int positionForSelection = getPositionForSection(section);viewHolder.tvLetter.setOnClickListener(null);if (position == positionForSelection) {viewHolder.tvLetter.setVisibility(View.VISIBLE);//把拼音转成大写字母,并取首字母    toUpperCase()  转换为大写字母String firstLetter = list.get(position).getSortLetters().substring(0, 1).toUpperCase();// 正则表达式,判断首字母是否是英文字母if (firstLetter.matches("[A-Z]")) {
//              给通讯录好友排序(按照从A-Z的顺序)Collections.sort(list, new PinyinComparator());//给控件设置值viewHolder.tvLetter.setText(firstLetter);} else {viewHolder.tvLetter.setText("#");}} else {viewHolder.tvLetter.setVisibility(View.GONE);}Glide.with(mContext).load(list.get(position).getImg()).into(viewHolder.imgHead);viewHolder.tvTitle.setText(list.get(position).getName());return convertView;}final static class ViewHolder {ImageView imgHead;TextView tvLetter;TextView tvTitle;}@Overridepublic Object[] getSections() {return null;}@Overridepublic int getPositionForSection(int section) {for (int i = 0; i < getCount(); i++) {String sortStr = list.get(i).getSortLetters();char firstChar = sortStr.toUpperCase().charAt(0);if (firstChar == section) {return i;}}return -1;}@Overridepublic int getSectionForPosition(int position) {return list.get(position).getSortLetters().toUpperCase().charAt(0);}
}

适配器里的xml布局

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_vertical"android:orientation="vertical"><TextViewandroid:id="@+id/catalog"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#F9F9F9"android:paddingBottom="5dp"android:paddingLeft="20dp"android:paddingTop="5dp"android:text="A"android:textColor="#454545" /><!--<TextViewandroid:id="@+id/line"android:layout_width="match_parent"android:layout_height="1px"android:background="@color/green_light" />
--><LinearLayoutandroid:id="@+id/content"android:layout_width="match_parent"android:layout_height="60dp"android:background="@color/white"android:orientation="horizontal"android:paddingBottom="5dp"android:paddingLeft="10dp"android:paddingRight="10dp"android:paddingTop="5dp"><ImageViewandroid:id="@+id/book_head"android:layout_width="45dp"android:layout_height="45dp"android:layout_gravity="center_vertical"android:layout_marginLeft="10dp"android:src="@color/green_light" /><TextViewandroid:id="@+id/book_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_marginLeft="10dip"android:ellipsize="end"android:gravity="center_vertical"android:singleLine="true"android:text="xxxx"android:textColor="#323232"android:textSize="16sp" /></LinearLayout></LinearLayout>

3.实现右侧的字母导航

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.ColorDrawable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;/***  2018/4/16.* 侧边栏 SideBar*/public class SideBar extends View {//触摸事件(用的接口回调)private OnTouchingLetterChangedListener onTouchingLetterChangedListener;//26个字母public static String[] b = {"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 int choose = -1;// 选中private TextView mTextDialog;public void setTextView(TextView mTextDialog) {this.mTextDialog = mTextDialog;}public SideBar(Context context) {super(context);}public SideBar(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}public SideBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint paint = new Paint();int height = getHeight();//获取高度int width = getWidth();//获取宽度int singleHeight = height / b.length;//获取每一个字母的高度for (int i = 0; i < b.length; i++) {paint.setColor(Color.parseColor("#838383"));//未选中的颜色paint.setTextSize(30);paint.setAntiAlias(true);//抗锯齿功能// 选中的状态if (i == choose) {paint.setColor(Color.BLACK);//选中的颜色paint.setFakeBoldText(false); //true为粗体,false为非粗体            }}// x坐标等于中间-字符串宽度的一半.float xPos = width / 2 - paint.measureText(b[i]) / 2;float yPos = singleHeight * i + singleHeight;canvas.drawText(b[i], xPos, yPos, paint);paint.reset();// 重置画笔}}@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {final int action = event.getAction();final float y = event.getY();// 点击y坐标final int oldChoose = choose;final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;final int c = (int) (y / getHeight() * b.length);// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.switch (action) {case MotionEvent.ACTION_UP:setBackgroundDrawable(new ColorDrawable(0x00000000));choose = -1;//invalidate();if (mTextDialog != null) {mTextDialog.setVisibility(View.INVISIBLE);}break;default:setBackgroundColor(Color.TRANSPARENT);if (oldChoose != c) {  //判断选中字母是否发生改变if (c >= 0 && c < b.length) {if (listener != null) {listener.onTouchingLetterChangedListener(b[c]);}if (mTextDialog != null) {mTextDialog.setText(b[c]);mTextDialog.setVisibility(View.VISIBLE);}choose = c;invalidate();}}break;}return true;}public void setOnTouchingLetterChangedListener(OnTouchingLetterChangedListener onTouchingLetterChangedListener) {this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;}public interface OnTouchingLetterChangedListener {void onTouchingLetterChangedListener(String s);}
}

在设置数据的页面把SideBar和Dialog绑定再一起,然后初始化监听

  protected void initView() {
//        把SideBar和Dialog绑定mSideBar.setTextView(mDialog);mSideBar.setOnTouchingLetterChangedListener(new SideBar.OnTouchingLetterChangedListener() {@Overridepublic void onTouchingLetterChangedListener(String s) {// 该字母首次出现的位置int position = adapter.getPositionForSection(s.charAt(0));if (position != -1) {mListView.setSelection(position);}}});}

Android仿微信通讯录相关推荐

  1. 【Android 仿微信通讯录 导航分组列表-上】使用ItemDecoration为RecyclerView打造带悬停头部的分组列表

    *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 转载请标明出处: http://blog.csdn.net/zxt0601/article/details/52355199 本文 ...

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

    前言: 仿微信通讯录搜索功能,通过汉字或拼音首字母找到匹配的联系人并显示匹配的位置 一:先看效果图 字母索引 搜索匹配 二:功能分析 1:汉字转拼音 通讯录汉字转拼音(首个字符当考虑姓氏多音字), 现 ...

  3. android 通讯录 首字母索引,android仿微信通讯录搜索(匹配拼音,字母,索引位置标记颜色)...

    前言: 仿微信通讯录搜索功能,通过汉字或拼音首字母找到匹配的联系人并显示匹配的位置 一:先看效果图 字母索引 搜索匹配 二:功能分析 1:汉字转拼音 通讯录汉字转拼音(首个字符当考虑姓氏多音字), 现 ...

  4. 【Android 仿微信通讯录 导航分组列表-下】自定义View为RecyclerView打造右侧索引导航栏IndexBar

    本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 转载请标明出处: http://blog.csdn.net/zxt0601/article/details/52420706 本文出 ...

  5. Android 仿微信通讯录

    这篇写下常用的类似通讯录似得效果    右边自定义一个sidebar  左边使用listview实现 效果如下: 1.自定义SideBar ①重写onDraw     计算每个字母所占的高度  就是整 ...

  6. Android 仿微信通讯录 导航分组列表-上】使用ItemDecoration为RecyclerView打造带悬停头部的分组列表

    本文是Android导航分组列表系列上,因时间和篇幅原因分上下,最终上下合璧,完整版效果如下:   上部残卷效果如下:两个ItemDecoration,一个实现悬停头部分组列表功能,一个实现分割线(官 ...

  7. android 仿微信demo————微信通讯录界面功能实现(移动端,服务端)

    android 仿微信demo----微信启动界面实现 android 仿微信demo----注册功能实现(移动端) android 仿微信demo----注册功能实现(服务端) android 仿微 ...

  8. php仿微信底部菜单,Android实现简单底部导航栏 Android仿微信滑动切换效果

    Android仿微信滑动切换最终实现效果: 大体思路: 1. 主要使用两个自定义View配合实现; 底部图标加文字为一个自定义view,底部导航栏为一个载体,根据需要来添加底部图标; 2. 底部导航栏 ...

  9. android仿微信的activity平滑水平切换动画,Android实现简单底部导航栏 Android仿微信滑动切换效果...

    Android实现简单底部导航栏 Android仿微信滑动切换效果 发布时间:2020-10-09 19:48:00 来源:脚本之家 阅读:96 作者:丶白泽 Android仿微信滑动切换最终实现效果 ...

最新文章

  1. 07-图6 旅游规划 (25分)(以此感谢zyx佬)
  2. 华为为什么能成全球第一?告诉你三个真相!
  3. vue生命周期图示中英文版Vue实例生命周期钩子
  4. SVM支持向量机(下)
  5. boost::thread_group相关的测试程序
  6. 受控组件和非受控组件
  7. python语言-Python Insider
  8. 我悲惨的人生,该死的UPX壳,谁能救救我
  9. 经典领导选举算法:Bully 算法
  10. 【并行计算-CUDA开发】GPGPU OpenCL/CUDA 高性能编程的10大注意事项
  11. 数据库问题6-將系統資料表對應至系統檢視
  12. ExtJS002Window创建
  13. .net ajax 保存文件,.net ajax式上传文件
  14. 三菱PLC连接威纶通触摸屏
  15. error LNK2019: 无法解析的外部符号 main,函数 “int __cdecl __scrt_common_main_seh(void)“ (?__scrt_common_main_seh
  16. dependencyManagement使用简介
  17. markdown编写操作手册
  18. 亲水性小分子PEG DBCO-PEG4-酸,1416711-60-8可以进行点击化学反应
  19. usnews2015美国大学计算机排名,2019USNews美国大学计算机专业排名
  20. IT行业前景真的好吗_转IT学什么语言好?

热门文章

  1. 应力应变基础理论分析
  2. HTML5 游戏开发快速提升
  3. 风寒感冒和风热感冒 区别
  4. C指针原理(32)--C语言-pvm并行计算
  5. 阿里云API请求签名失败的解决办法
  6. 免费小程序转码工具(小程序转码机器人)业务推广必备
  7. Ubuntu 21 .1安装wps office 2019并解决字体缺失问题教程
  8. 彻底搞懂AQS-重点方法精讲 [并发劝退- 哭唧唧]
  9. 国内Linux笔记天花板,不接受反驳!
  10. 回顾使用云桌面的那些经验