效果图:
实现原理:
把联系人的姓名的每一个字,保存在一个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>
<?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); } @Override public int getCount() { // TODO Auto-generated method stub return data.size(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return data.get(arg0); } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public View getView(final int indext, View convertView, ViewGroup parent) { // TODO Auto-generated method stub GridViewHolder 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() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub Log.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;
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