The implementation of the function is combined with many excellent implementations on the Internet. Let's look at the small optimization.
Implementation ideas:
1. Get the mobile phone contact list: query the contact list through URI uri = URI. parse ("content: // com. Android. Contacts/data/phones ").
2. There are many contact fields, including name = "name", number = "Number", sort_key = "sort_key"; name, phone number, and very important sort_key fields,
In the previous project, it was converted through the imported pinyin package, which was learned online and very good.
3 get contact list, displayed through listview, displayed when the A--Z group display, this also can do, because the sort_key has been obtained from the A--Z sort, if it is determined whether it belongs to the same character, it is not displayed. If it is not, it is displayed. At the same time, set the group title.
4. After the letter group is displayed completely, I found that there are more than one contact person. It is also a great deal of effort to locate a group. If I add a search on it, I am too lazy to enter it because of the mobile phone, the operation remains unchanged. If you can select and directly locate
In this group, it is easy, because people are more lazy, so you can feel it without effort, and the experience is good.
So I don't need to talk about it. I need an uppercase vertical alphabet on the right, which can be selected and located in the group of the letter.
It is easy to locate the group. You can use setselection (postion) as a method for listview to locate the group.
The key is to click on the right side and know the letters you click:
5. The first is layout. There are many layout methods. The direct frame layout defines the layout on the right, but the layout is relatively simple.
Package COM. droid; import Java. util. arraylist; import Java. util. hashmap; import Java. util. list; import Java. util. regEx. pattern; import android. app. activity; import android. content. asyncqueryhandler; import android. content. contentresolver; import android. content. contentvalues; import android. content. context; import android. database. cursor; import android. graphics. pixelformat; import android.net. uri; import Andro Id. OS. bundle; import android. OS. handler; import android. view. layoutinflater; import android. view. view; import android. view. viewgroup; import android. view. viewgroup. layoutparams; import android. view. windowmanager; import android. widget. baseadapter; import android. widget. listview; import android. widget. textview; import COM. droid. myletterlistview. ontouchingletterchangedlistener; public class contactlist extends Activity {private baseadapter adapter; private listview personlist; private textview overlay; private myletterlistview letterlistview; private asyncqueryhandler asyncquery; Private Static final string name = "name", number = "Number ", sort_key = "sort_key"; private hashmap <string, integer> alphaindexer; // stores the first letter of the Chinese pinyin alphabet and its corresponding list location private string [] sections; // store the first letter of Chinese pinyin private handler; priv Ate overlaythread; @ override public void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. main); personlist = (listview) findviewbyid (R. id. list_view); letterlistview = (myletterlistview) findviewbyid (R. id. myletterlistview01); letterlistview. setontouchingletterchangedlistener (New letterlistviewlistener (); asyncquery = new myasyncqueryh Andler (getcontentresolver (); alphaindexer = new hashmap <string, integer> (); handler = new handler (); overlaythread = new overlaythread (); initoverlay ();} @ override protected void onresume () {super. onresume (); Uri uri = Uri. parse ("content: // COM. android. contacts/data/phones "); string [] projection = {" _ id "," display_name "," data1 "," sort_key "}; asyncquery. startquery (0, null, Uri, projection, NUL L, null, "sort_key collate localized ASC");} // asynchronously query the contact private class myasyncqueryhandler extends asyncqueryhandler {public myasyncqueryhandler (contentresolver Cr) {super (CR );} @ override protected void onquerycomplete (INT token, object cookie, cursor) {If (cursor! = NULL & cursor. getcount ()> 0) {list <contentvalues> List = new arraylist <contentvalues> (); cursor. movetofirst (); For (INT I = 0; I <cursor. getcount (); I ++) {contentvalues CV = new contentvalues (); cursor. movetoposition (I); string name = cursor. getstring (1); string number = cursor. getstring (2); string sortkey = cursor. getstring (3); system. out. println (sortkey); If (number. startswith ("+ 86") {CV. Put (name, name); cv. put (number, number. substring (3); // remove + 86 cv. put (sort_key, sortkey);} else {cv. put (name, name); cv. put (number, number); cv. put (sort_key, sortkey);} List. add (CV);} If (list. size ()> 0) {setadapter (list) ;}}} private void setadapter (list <contentvalues> List) {adapter = new listadapter (this, list); personlist. setadapter (adapter);} private class listadapter extends Base Adapter {private layoutinflater Inflater; private list <contentvalues> list; Public listadapter (context, list <contentvalues> List) {This. inflater = layoutinflater. from (context); this. list = List; alphaindexer = new hashmap <string, integer> (); sections = new string [list. size ()]; for (INT I = 0; I <list. size (); I ++) {// string currentstr = getalpha (list. get (I ). getasstring (sort_ke Y); // The first letter of the Chinese pinyin. If it does not exist, it is "" string previewstr = (I-1)> = 0? Getalpha (list. Get (I-1). getasstring (sort_key): ""; if (! Previewstr. equals (currentstr) {string name = getalpha (list. get (I ). getasstring (sort_key); alphaindexer. put (name, I); sections [I] = Name ;}}@ 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, viewgro Up parent) {viewholder holder; If (convertview = NULL) {convertview = Inflater. inflate (R. layout. list_item, null); holder = new viewholder (); holder. alpha = (textview) convertview. findviewbyid (R. id. alpha); holder. name = (textview) convertview. findviewbyid (R. id. name); holder. number = (textview) convertview. findviewbyid (R. id. number); convertview. settag (holder);} else {holder = (viewholder) convert View. gettag ();} contentvalues CV = List. get (position); holder. name. settext (cv. getasstring (name); holder. number. settext (cv. getasstring (number); string currentstr = getalpha (list. get (position ). getasstring (sort_key); // the current letter string previewstr = (position-1)> = 0? Getalpha (list. Get (position-1). getasstring (sort_key): ""; if (! Previewstr. equals (currentstr) {holder. alpha. setvisibility (view. visible); holder. alpha. settext (currentstr);} else {holder. alpha. setvisibility (view. gone);} return convertview;} private class viewholder {textview Alpha; textview name; textview number ;}// the pop-up prompt box for initializing the first letter of Chinese pinyin (Private void initoverlay () {layoutinflater Inflater = layoutinflater. from (this); overlay = (textview) Inflater. inflate (R. layo Ut. overlay, null); overlay. setvisibility (view. invisible); windowmanager. layoutparams Lp = new windowmanager. layoutparams (layoutparams. wrap_content, layoutparams. wrap_content, windowmanager. layoutparams. type_application, windowmanager. layoutparams. flag_not_focusable | windowmanager. layoutparams. flag_not_touchable, pixelformat. translucent); windowmanager = (windowmanager) This. getsystemservi Ce (context. window_service); windowmanager. addview (overlay, LP);} private class letterlistviewlistener implements ontouchingletterchangedlistener {@ overridepublic void ontouchingletterchanged (final string s) {If (alphaindexer. get (s )! = NULL) {int position = alphaindexer. get (s); personlist. setselection (position); overlay. settext (sections [position]); overlay. setvisibility (view. visible); handler. removecallbacks (overlaythread); // The task is executed after a delay of one second, making overlay invisible to handler. postdelayed (overlaythread, 1500) ;}}// set overlay to private class overlaythread implements runnable {@ overridepublic void run () {overlay. setvisibility (view. gone) ;}}// obtain the first letter of Chinese pinyin private string getalpha (string Str) {If (STR = NULL) {return "#" ;}if (Str. trim (). length () = 0) {return "#";} Char c = Str. trim (). substring (0, 1 ). charat (0); // regular expression to determine whether the first letter is the English letter pattern = pattern. compile ("^ [A-Za-Z] + {1} quot;); If (pattern. matcher (C + ""). matches () {return (C + ""). touppercase () ;}else {return "#";}}}
package com.droid;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Typeface;import android.text.style.TypefaceSpan;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;public class MyLetterListView extends View {OnTouchingLetterChangedListener onTouchingLetterChangedListener;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"};int choose = -1;Paint paint = new Paint();boolean showBkg = false;public MyLetterListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public MyLetterListView(Context context, AttributeSet attrs) {super(context, attrs);}public MyLetterListView(Context context) {super(context);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if(showBkg){ canvas.drawColor(Color.parseColor("#40000000"));} int height = getHeight(); int width = getWidth(); int singleHeight = height / b.length; for(int i=0;i<b.length;i++){ paint.setColor(Color.WHITE); paint.setTypeface(Typeface.DEFAULT_BOLD); paint.setAntiAlias(true); if(i == choose){ paint.setColor(Color.parseColor("#3399ff")); paint.setFakeBoldText(true); } 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(); final int oldChoose = choose; final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener; final int c = (int) (y/getHeight()*b.length); switch (action) {case MotionEvent.ACTION_DOWN:showBkg = true;if(oldChoose != c && listener != null){if(c > 0 && c< b.length){listener.onTouchingLetterChanged(b[c]);choose = c;invalidate();}}break;case MotionEvent.ACTION_MOVE:if(oldChoose != c && listener != null){if(c > 0 && c< b.length){listener.onTouchingLetterChanged(b[c]);choose = c;invalidate();}}break;case MotionEvent.ACTION_UP:showBkg = false;choose = -1;invalidate();break;}return true;}@Overridepublic boolean onTouchEvent(MotionEvent event) {return super.onTouchEvent(event);}public void setOnTouchingLetterChangedListener(OnTouchingLetterChangedListener onTouchingLetterChangedListener) {this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;}public interface OnTouchingLetterChangedListener{public void onTouchingLetterChanged(String s);}}
<? XML version = "1.0" encoding = "UTF-8"?> <Relativelayout xmlns: Android = "http://schemas.android.com/apk/res/android" Android: layout_width = "match_parent" Android: layout_height = "match_parent"> <textviewandroid: Id = "@ + ID/Alpha" Android: layout_width = "fill_parent" Android: layout_height = "wrap_content" Android: paddingleft = "13dip" Android: Background = "#333333" Android: textcolor = "#99 CCFF" Android: textappearance = "? Android: textappearancemedium "Android: visibility =" gone "/> <imageviewandroid: Id =" @ + ID/image_view "Android: layout_width =" wrap_content "Android: layout_height = "wrap_content" Android: layout_alignparentleft = "true" Android: layout_marginright = "5.0dip" Android: src = "@ drawable/contact_list_icon" Android: layout_below = "@ ID/Alpha"/> <textview Android: Id = "@ + ID/Name" Android: textappearance = "? Android: textappearancemedium "Android: layout_width =" wrap_content "Android: layout_height =" wrap_content "Android: layout_marginleft =" 2.0dip "Android: layout_margintop =" 6.0dip "Android: layout_marginright = "5.0dip" Android: singleline = "true" Android: layout_torightof = "@ ID/image_view" Android: layout_aligntop = "@ ID/image_view"/> <textview Android: id = "@ + ID/number" Android: textappearance = "? Android: textappearancesmall "Android: ellipsize =" marquee "Android: layout_width =" wrap_content "Android: layout_height =" wrap_content"<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ListView android:id="@+id/list_view" android:layout_height="wrap_content" android:layout_width="fill_parent"android:scrollbars="none"android:cacheColorHint="#00000000" /> <com.droid.MyLetterListView android:id="@+id/MyLetterListView01" android:background="#40000000" android:layout_width="30dip" android:layout_height="fill_parent"android:layout_alignParentRight="true" /></RelativeLayout>
Android: singleline = "true" Android: textcolor = "# aaaaaa" Android: layout_below = "@ ID/Name" Android: layout_alignleft = "@ ID/Name" Android: layout_alignwithparentifmissing = "true"/> </relativelayout>
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:textSize="70sp" android:textColor="#3399ff" android:background="#ffffff" android:minWidth="80dip" android:maxWidth="80dip" android:padding="5dip" android:gravity="center" />
These are three layout files. Go back first. If you don't understand them, leave a message.
List_item.xml
Main. xml
Overlay. xml