效果图:

实现原理:

把联系人的姓名的每一个字,保存在一个ArrayList中,去除相同的姓氏,并且保存每个姓氏所对应在联系人列表中的位置,当用户点击相应的姓氏时,就跳转到对应的联系人列表姓氏对应的位置!

实现方法:

1.Hy_family_name_popup_sel.xml(百家姓弹出选择窗口界面的布局文件)

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/myPopupViewFamilyNameLL"android:layout_width="fill_parent"android:layout_height="wrap_content"  android:layout_gravity="center"android:background="#000000"android:gravity="center"><GridView android:id="@+id/myPopupViewFamilyNameGV"android:layout_width="fill_parent"android:layout_height="wrap_content"  android:numColumns="5"android:gravity="center"android:layout_gravity="center"android:focusable="false"android:clickable="false"android:descendantFocusability="blocksDescendants">     </GridView></LinearLayout>

2.Hy_family_name_item.xml(GridView item的布局文件)

<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/myFamilyNameItem"android:layout_width="fill_parent"android:layout_height="wrap_content"  android:layout_gravity="center"android:gravity="center" android:textSize="40sp"android:textColor="#FFFFFF"android:clickable="true"android:focusable="true"android:focusableInTouchMode="true"/>

3.HYFamilyNameAdapter.java(GridView 的自定义adapter):

在这个文件中,我们定义了一个interface OnFamilyNameSelectListener,这个接口的主要作用是,把点击姓氏,进行跳转的操作,此接口可以方便在需要时进行实现,是一个开发的利器噢!!

package com.android.contacts.list;import java.util.ArrayList;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.android.contacts.R;public class HYFamilyNameAdapter extends  BaseAdapter{public static OnFamilyNameSelectListener onFamilyNameSelectListener;public Context context = null;public ArrayList<String> data;public LayoutInflater mLayoutInflater;public HYFamilyNameAdapter(Context context,ArrayList<String> data){      this.context = context;this.data = data;      mLayoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);   }@Overridepublic int getCount() {// TODO Auto-generated method stubreturn data.size();}@Overridepublic Object getItem(int arg0) {// TODO Auto-generated method stubreturn data.get(arg0);}@Overridepublic long getItemId(int arg0) {// TODO Auto-generated method stubreturn arg0;}@Overridepublic View getView(final int indext, View convertView, ViewGroup parent) {// TODO Auto-generated method stubGridViewHolder myGVHolder = null;if(convertView == null){Log.i("familiNames","convertView == null:");convertView = mLayoutInflater.inflate(R.layout.hy_family_name_item, null);myGVHolder = new GridViewHolder();myGVHolder.myTextView = (TextView)convertView.findViewById(R.id.myFamilyNameItem);myGVHolder.myTextView.setOnClickListener(new OnClickListener() {            @Overridepublic void onClick(View arg0) {// TODO Auto-generated method stubLog.i("familiNames","onItemClick1:"+indext);OnFamilyNameSelectListener listener = onFamilyNameSelectListener;if(listener != null){listener.onFamilyNameSelect(indext);Log.i("familiNames","listener.onFamilyNameSelect(indext)");}               }});convertView.setTag(myGVHolder);}else{myGVHolder = (GridViewHolder)convertView.getTag();Log.i("familiNames","convertView != null:");}              if(data.get(indext) != null){myGVHolder.myTextView.setText(data.get(indext));  }return convertView;}public final class GridViewHolder{public TextView myTextView = null;}public void setOnFamilyNameSelectListener(OnFamilyNameSelectListener onFamilyNameSelectListener){this.onFamilyNameSelectListener = onFamilyNameSelectListener;      }public interface OnFamilyNameSelectListener{public void onFamilyNameSelect(int indext);}}

4.主文件代码:

(1)引进一些包

import android.widget.ScrollView;
import android.widget.GridView;
import android.widget.Adapter;
import com.android.contacts.list.HYFamilyNameAdapter.OnFamilyNameSelectListener;
import com.mediatek.common.featureoption.FeatureOption;
import android.view.Gravity;

(2)定义一个总开关

public static boolean isOpenFamilyNames = true;

(3)定义一些变量:

private ImageButton btnFooterFamiliNames;private View myPopUpView;
private GridView myPopupViewFamilyNameGV;
private HYFamilyNameAdapter myGridViewAdapter;
private MyAsyncQueryHandler asyncQuery;
private static final String NAME = "name", NUMBER = "number", SORT_KEY = "sort_key",FAMILY_NAME="family_name";
private HashMap<String, Integer> familyNameIndexer;
private  ArrayList<String> familyNameSections;
private HashMap<String, Integer> alphaIndexer;
private TextView mShowOverlay;private String [] sections;

(4)定义显示开头入口

isOpenFamilyNames = FeatureOption.HY_FAMILY_NAME_SUPPORT;
if(isOpenFamilyNames == true){btnFooterFamiliNames=(ImageButton)listLayout.findViewById(R.id.btn_footer_familiNames);btnFooterFamiliNames.setOnClickListener(this);
}else{btnFooterFamiliNames=(ImageButton)listLayout.findViewById(R.id.btn_footer_familiNames);btnFooterFamiliNames.setVisibility(View.GONE);
}

(5)快速查询联系人数据:

Uri uri = Uri.parse("content://com.android.contacts/data/phones");
//String[] projection = { "_id", "display_name", "data1", "sort_key" };  String[] projection = { "_id", "display_name", "data1", "sort_key","data3" };
asyncQuery.startQuery(0, null, uri, projection, null, null,  "sort_key COLLATE LOCALIZED asc");
private class MyAsyncQueryHandler extends AsyncQueryHandler {                    public MyAsyncQueryHandler(ContentResolver cr) {  super(cr);  alphaIndexer = new HashMap<String, Integer>(); familyNameIndexer = new HashMap<String, Integer>();       }  @Override  protected void onQueryComplete(int token, Object cookie, Cursor cursor) {  int iCount = cursor.getCount();if (cursor != null && iCount > 0) {  List<ContentValues> list = new ArrayList<ContentValues>();  cursor.moveToFirst();  int i;ContentValues cv =null;for (i = 0; i < iCount; i++) {cv = new ContentValues();  cursor.moveToPosition(i);  //String family_name = cursor.getString(4);String name = cursor.getString(1); // String name = cursor.getString(1);  //String number = cursor.getString(2);  String sortKey = cursor.getString(3);//cv.put(FAMILY_NAME, family_name);  cv.put(NAME, name);//cv.put(NAME, name);  // cv.put(NUMBER, number);  cv.put(SORT_KEY, sortKey);  list.add(cv);  }  if (list.size() > 0) {  onLoadMap(list);  }  }  }  public void onLoadMap(List<ContentValues> list){int iCount=list.size();int i;sections = new String[iCount];//familyNameSections = new String[iCount];familyNameSections = new ArrayList<String>();for (i = 0; i < iCount; i++) {String currentStr = getAlpha(list.get(i).getAsString(SORT_KEY));//String curFamilyName = getFamilyNameIndext(list.get(i).getAsString(FAMILY_NAME));String curFamilyName = getFamilyNameIndext(list.get(i).getAsString(NAME)).substring(0, 1);Log.i("familiNames","curFamilyName:"+curFamilyName);  String previewStr = (i - 1) >= 0 ? getAlpha(list.get(i - 1).getAsString(SORT_KEY)) : " ";//String preFamilyName = (i - 1) >= 0 ? getFamilyNameIndext(list.get(i - 1).getAsString(FAMILY_NAME)) : " ";String preFamilyName = (i - 1) >= 0 ? (getFamilyNameIndext(list.get(i - 1).getAsString(NAME)).substring(0, 1)) : " ";Log.i("familiNames","preFamilyName:"+preFamilyName);if (!preFamilyName.equals(curFamilyName)) {//String familyName = getFamilyNameIndext(list.get(i).getAsString(FAMILY_NAME));String familyName = getFamilyNameIndext(list.get(i).getAsString(NAME)).substring(0, 1);Log.i("familiNames","familyName:"+familyName);if(familyName != null){familyNameIndexer.put(familyName, i);  //familyNameSections[i] = familyName;familyNameSections.add(familyName);}}if (!previewStr.equals(currentStr)) {String name = getAlpha(list.get(i).getAsString(SORT_KEY));alphaIndexer.put(name, i);  sections[i] = name;}}}}  private static String getFamilyNameIndext(String str) {  if (str == null) {    return "#";  } if (str.trim().length() == 0) {  return "#";  } return str;}private static String getAlpha(String str) {  if (str == null) {  return "#";  }  if (str.trim().length() == 0) {  return "#";  }  char c = str.trim().substring(0, 1).charAt(0);  Pattern pattern = Pattern.compile("^[A-Za-z]+$");  if (pattern.matcher(c + "").matches()) {  return (c + "").toUpperCase();  } else {  return "#";  }  }  

(6)实时实现点击姓氏,跳转接口:

private  OnFamilyNameSelectListener onFamilyNameSelectListener=new OnFamilyNameSelectListener(){public void onFamilyNameSelect(int indext){if(mAllContactsAdapter !=null){Log.i("familiNames","onFamilyNameSelectListener.onFamilyNameSelect");String familyName = familyNameSections.get(indext);int position = familyNameIndexer.get(familyName);              myPopUpView.setVisibility(View.GONE);mListView.setSelection(position);              }}
};

(7)显示姓氏选择界面:

private void popUpFamilyNamesSele(){myPopUpView = LayoutInflater.from(getActivity()).inflate(R.layout.hy_family_name_popup_sel,null);myPopupViewFamilyNameGV = (GridView)myPopUpView.findViewById(R.id.myPopupViewFamilyNameGV);   myGridViewAdapter = new HYFamilyNameAdapter(getActivity(),familyNameSections);myGridViewAdapter.setOnFamilyNameSelectListener(onFamilyNameSelectListener);                                 myPopupViewFamilyNameGV.setAdapter(myGridViewAdapter);WindowManager.LayoutParams lp = new WindowManager.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.TYPE_APPLICATION,WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE ,PixelFormat.TRANSLUCENT);lp.gravity = Gravity.CENTER;WindowManager windowManager = (WindowManager) this.getActivity().getSystemService(Context.WINDOW_SERVICE);windowManager.addView(myPopUpView, lp);
}private void onFamiliNames(){Log.i("familiNames","onFamiliNames");         popUpFamilyNamesSele();}

(8)点击监听入口:

public void onClick(View v) {switch(v.getId()){case R.id.btn_footer_familiNames:{        onFamiliNames();break;          }               }
}

参考资料:

1.实现ListView A~Z快速索引
http://blog.csdn.net/appte/article/details/10306341

android开发笔记之联系人百家姓功能的实现相关推荐

  1. 云炬Android开发笔记 6启动图功能开发与封装

    阅读目录 1.启动图功能开发与封装(倒计时效果) 2. 持久化 3.倒计时工具库封装 4.第一个启动页面的倒计时 5.启动图功能开发与封装(轮播效果) 5.1 轮播图片的添加 5.2 指示器的添加 6 ...

  2. 云炬Android开发笔记 7登陆注册功能开发

    阅读目录 1.注册UI及验证逻辑实现 1.1 布局 1.2 注册信息的验证和逻辑 2.登录UI及验证逻辑实现 2.1 布局 2.2 登录的逻辑框架 3.服务器数据简单介绍 3.1 服务器的数据 3.2 ...

  3. 云炬Android开发笔记 17商品详情功能开发

    阅读目录 1.商品详情ui框架设计 1.1 自定义圆形控件 1.2 底部栏的布局 1.3 整体布局 2.商品详情UI-MD风格伸缩渐变效果实现 2.1 ui的绑定 2.2 服务器中商品详情页的数据的取 ...

  4. Android开发笔记(八十三)多语言支持

    汉字转拼音 app中有许多场景要对汉字排序,例如通讯录姓名.商品名称.城市名称等等,这些汉字词汇通常是按照拼音排序,所以产生了把汉字转换为拼音的需求. Android自带库 Android自带的联系人 ...

  5. Android开发笔记(七十)反编译初步

    查看平台源码 查看内核源码 Android的内核源码很大,有几个G,仔细找找网上有许多下载的地方.作为普通开发者,一般不需要阅读内核源码,但一点都不了解好像也不行,因为实际开发中有时候就得会那么一点点 ...

  6. Android开发笔记(六十四)网页加载与JS调用

    内置浏览器 网页视图WebView 如果一个网站已经有现成的网页及业务逻辑,那么使用WebView将其内嵌到app中,省去了app重画页面与http通信的事情,无疑是更经济的做法.WebView就是A ...

  7. Android开发笔记(五十五)手机设备基本操作

    获取手机基本信息 手机的基本信息分两类,一类是与电话有关的信息,另一类是设备自身的信息. 与电话有关的信息可由TelephonyManager类获得,常用的参数与对应的方法如下所示: 网络运营商名称 ...

  8. 《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:概述

    1.前言 数据生产和数据展示是常见的两大专业级移动GIS应用场景,这里我们针对数据生产环节的ArcGIS的离在线一体化技术给大家做一个基本的介绍和梳理. 使用ArcGIS离在线一体化技术首先需要以下基 ...

  9. 《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据同步...

    1.前言 上一篇文章中我们实现了离线要素的编辑操作,这一篇中主要介绍离在线一体化技术中最后一个环节离线数据的同步功能,通过对数据的上传,服务器端的版本化管理,实现数据生产管理的整个流程. 转载请注明出 ...

最新文章

  1. python程序员的工作内容_每个Python程序员都要知道的日志实践
  2. 面包板上的高频放大电路
  3. 卡尔曼滤波器_使用卡尔曼滤波器和路标实现机器人定位
  4. wxWidgets:wxRibbonToolBar类用法
  5. JavaFX中的塔防
  6. 使用uicollectionView时需要注意的问题
  7. hdoj-2028-Lowest common multiple plus
  8. 盘点国内高投资低票房的电影巨制
  9. 阿里巴巴fastjson @JSONField 注解说明
  10. 解决Eclipse无法添加Tomcat服务器的问题
  11. 实现一个高效C++委托类(多分派)
  12. iOS 中delegate的理解与使用(传值)
  13. 进程调度(一)--linux内核设计与实现读书笔记
  14. 读书笔记之大数据采集与预处理
  15. 朗文当代高级英语辞典android,朗文当代高级英语辞典最新版下载-朗文当代高级英语辞典第6版appv4.5.2 安卓版 - 极光下载站...
  16. 寻找道路(NOIP2014)神奇之题。。
  17. (PDF目录)自动生成PDF书签目录
  18. jQuery 中console.log什么意思
  19. 一些基于 D3.js 的图表库
  20. javaEE核心框架之 Mybatis ( 一 )

热门文章

  1. 【华为OD】| 网上商城优惠活动_逻辑分析
  2. 是非人生 — 一个菜鸟程序员的5年职场路 第9节
  3. Js、Vue阻止事件冒泡行为
  4. 三角波的傅里叶变换对_《傅里叶光学(一)》 复数、特殊函数和冲激函数
  5. JQ拖曳事件mouseup失效的解决办法
  6. Linux开机启动过程-centos7
  7. 3轴/6轴/9轴传感器是什么, 加速计/陀螺仪/磁力计又是什么?
  8. 相机内参,外参的物理意义
  9. 亿美软通一键登录升级:扩大适用范围、更高安全保障
  10. 横向数据(按行)的最大值和最小值的SQL语句的编写 !