Apps only involve contact people's interfaces, almost all alphabetically and in the way the navigation bar is arranged. Since this demand so fire, so began to learn related content, this article is I through the reference on the Internet data independently prepared and summarized, I hope that more or less for everyone to help, write a bad, but also asked you to advise friends.
The effect chart is as follows:
To achieve this effect, you need three knowledge points:
1: Pinyin classification of the string
2:expandablelistview Level Two extended list
3: Right Letter Category View
Let's start with a single one to understand the solution and then code.
To achieve the letter classification:
The alphabetic classification is divided into three small points: one is to convert Chinese into pinyin, one is to order alphabetically, and the other is to show only the first one with the same initials in Chinese.
1, the Chinese into pinyin, where the use of a toolkit, that is, Pinyin4j-2.5.0.jar. Website address:http://pinyin4j.sourceforge.net/
Click on the download to import the project. (As for tutorials, a lot of online)
Here we only need to use the code that converts Chinese into pinyin.
Pinyinutils.java 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];
} else
output = = java.lang.Character.toString (Curchar);
}
catch ( Badhanyupinyinoutputformatcombination e) {
e.printstacktrace ();
}
return output;
}
2, the implementation of alphabetical order, the use of the comparator interface with Java, using the previously acquired Pinyin, get the first letter and according to the ASCII value to achieve the order.
private int sort (Personbean lhs, Personbean RHS) {
//Get ASCII value
int lhs_ascii = Lhs.getfirstpinyin (). toUpperCase ( ). charAt (0);
int rhs_ascii = Rhs.getfirstpinyin (). toUpperCase (). charAt (0);
Judge if the letter is not, then the letter
if (Lhs_ascii < | | lhs_ascii >) return
1;
else if (Rhs_ascii < | | rhs_ascii >)
return-1;
else return
Lhs.getpinyin (). CompareTo (Rhs.getpinyin ());
}
3. The letters only appear in front of the first in the Chinese with the same first letter. Here is a small tip, where the layout of the letters and the layout of Chinese names are stored in the layout of the ListView item.
The item is laid out as follows:
<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android= "http://schemas.android.com/apk/res/" Android "Android:layout_width=" Match_parent "android:layout_height=" match_parent "android:orientation=" vertical " > <!--This TextView is the--> <textview android:id= "@+id/tv_lv_item_tag" android:layout_width=, which displays the letters. NT "android:layout_height=" 20DP "android:background=" "#e6e6e6" android:gravity= "center_vertical" Android:paddinglef t= "10dip" android:text= "Z" android:visibility= "visible/> <relativelayout android:layout_width=" match_parent "android:layout_height=" wrap_content "> <view android:id=" @+id/view_lv_item_line "android:layout_width=" Match_parent "android:layout_height=" 0.5dip "android:background=" #174465 "android:layout_marginleft=" 10dip "an droid:layout_marginright= "20dip"/> <imageview android:id= "@+id/iv_lv_item_head" android:layout_width= "WR" Ap_content "Android:layout_height=" WRap_content "android:src=" @drawable/ic_launcher "android:layout_below=" @id/view_lv_item_line "Android:layout_marg inleft= "5DP"/> <textview android:id= "@+id/tv_lv_item_name" android:layout_width= "Wrap_content" Android:
layout_height= "Wrap_content" android:layout_centervertical= "true" android:layout_torightof= "@id/iv_lv_item_head" android:layout_marginleft= "5dip" android:text= "kin"/> </RelativeLayout> </LinearLayout>
The decision whether to display the letters is by determining whether the current item's position is equal to the index of the first letter in Chinese that appears in the item.
If it is equal, the first time it appears, you need to display the letter, otherwise the letter will not appear. And such a judgment, there is a prerequisite, that is, the Chinese phonetic order must be sorted alphabetically, which is the need for us to sort in the last step.
to implement the letter navigation to the right:
The right side of the letter navigation, its essence is a custom view. In addition to drawing the interface, attention should be paid to the handling of touch events, as well as the use of callback mechanisms (which are used in many places). This is more important, directly on the code.
Package com.suse.contact;
Import Android.content.Context;
Import Android.graphics.Canvas;
Import Android.graphics.Color;
Import Android.graphics.Paint;
Import Android.graphics.Typeface;
Import android.graphics.drawable.ColorDrawable;
Import Android.util.AttributeSet;
Import android.view.MotionEvent;
Import Android.view.View;
Import Android.widget.TextView;
public class SideBar extends View {//Touch event private Ontouchingletterchangedlistener Ontouchingletterchangedlistener; 26 letters public static string[] A_z = {"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;//Select private Paint Paint = new Paint ();
Private TextView Mtextdialog; /** * Sets the TextView * for sidebar to display letters * @param mtextdialog/public void Settextview (TextView mtextdialog) {THIS.M
Textdialog = Mtextdialog; Public SideBar (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);
Public SideBar (context, AttributeSet attrs) {Super (context, attrs);
Public SideBar {Super (context);
/** * Rewrite this method * * protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas);
Gets focus to change the background color. int height = getheight ();//get corresponding height int width = getwidth (); Get the corresponding width int singleheight = height/a_z.length-2;//Get the height of each letter (here-2 is just for good looks) for (int i = 0; i < a_z.length i + +) {Paint.setcolor (Color.rgb (33, 65, 98));//Set Font color paint.settypeface (typeface.default_bold);//Set Font paint.se Tantialias (TRUE); Set anti-aliasing paint.settextsize (30); Sets the letter font size//checked status if (i = = choose) {Paint.setcolor ("#3399ff"));//Selected Letters change color PAINT.SETF Akeboldtext (TRUE);
Sets the font to bold}//x coordinates equal to the middle-half the width of the string.
float xpos = width/2-Paint.measuretext (A_z[i])/2;
float YPos = singleheight * i + singleheight; Canvas.drawtext (A_z[i], xpos, YPos, paint); DrawAll letters Paint.reset ()//Reset Brush}} @Override public boolean dispatchtouchevent (Motionevent event) {Final int
Action = Event.getaction ();
Final float y = event.gety ()//Click y-coordinate final int oldchoose = choose;
Final Ontouchingletterchangedlistener listener = Ontouchingletterchangedlistener;
Final int c = (int) (Y/getheight () * a_z.length)//Click the ratio of the Y coordinate to the total height *b the length of the array equals the number of clicks in B.
Switch (action) {case MotionEvent.ACTION_UP:setBackgroundDrawable (new colordrawable (0x00000000));
Choose = -1;//invalidate ();
if (Mtextdialog!= null) {mtextdialog.setvisibility (view.invisible);
} break;
Default:setbackgroundresource (R.drawable.sidebar_background);
if (Oldchoose!= c) {//Determine if the selected letter has changed if (c >= 0 && C < a_z.length) {if (listener!= null) {
Listener.ontouchingletterchanged (A_z[c]);
} if (Mtextdialog!= null) {Mtextdialog.settext (a_z[c)); Mtextdialog.setvisibility (View.visiBLE);
} choose = C;
Invalidate ();
}} break;
return true; /** * Outward Method * * @param ontouchingletterchangedlistener/public void Setontouchingletterchangedlisten ER (ontouchingletterchangedlistener ontouchingletterchangedlistener) {This.ontouchingletterchangedlistener = OnTou
Chingletterchangedlistener; /** * Interface * * * @author coder */public interface Ontouchingletterchangedlistener {public void OnT
Ouchingletterchanged (String s); }
}
Next is the code for mainactivity and Sortadapter.
MainActivity.java:package com.suse.contact;
Import java.util.ArrayList;
Import java.util.Collections;
Import java.util.List;
Import android.app.Activity;
Import Android.os.Bundle;
Import Android.widget.ListView;
Import Android.widget.TextView;
Import Com.suse.contact.SideBar.OnTouchingLetterChangedListener; /** * * @ClassName: Mainactivity * @Description: TODO (Describe the role of this class in one sentence) * @author Silver Meteor welcome criticism, guidance, Exchange qq:962455668 * * Publ
IC class Mainactivity extends activity {private ListView ListView;
Private Sortadapter Sortadapter;
Private list<personbean> data;
Private SideBar SideBar;
Private TextView Dialog;
@Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main);
Init (); Private list<personbean> GetData (string[] data) {list<personbean> Listarray = new Arraylist<personbea
N> (); for (int i = 0; i < data.length i++) {String Pinyin = Pinyinutils.getpingyin (Data[i]);
String fpinyin = pinyin.substring (0, 1). toUpperCase ();
Personbean person = new Personbean ();
Person.setname (Data[i]);
person.setpinyin (pinyin);
Regular expression to determine whether the first letter is an English letter if (Fpinyin.matches ("[A-z]")) {Person.setfirstpinyin (fpinyin);
else {person.setfirstpinyin ("#");
} listarray.add (person);
return listarray;
private void Init () {//TODO auto-generated method Stub sidebar = (sidebar) Findviewbyid (R.id.sidebar);
ListView = (ListView) Findviewbyid (R.id.listview);
Dialog = (TextView) Findviewbyid (R.id.dialog);
Sidebar.settextview (Dialog); Set the letter navigation touch listening Sidebar.setontouchingletterchangedlistener (new Ontouchingletterchangedlistener () {@Override public void Ontouchingletterchanged (String s) {//TODO auto-generated Method Stub//The position of the first occurrence of the letter int position = Sorta
Dapter.getpositionforselection (S.charat (0));
if (position!=-1) {listview.setselection (position);
}
}
}); data = GetData (getrEsources (). Getstringarray (r.array.listpersons));
The data needs to be sorted before it is placed in the adapter (Collections.sort, New Pinyincomparator ());
Sortadapter = new Sortadapter (this, data);
Listview.setadapter (Sortadapter); }
}
Sortadapter.java:
Package com.suse.contact;
Import java.util.List;
Import Android.content.Context;
Import Android.view.LayoutInflater;
Import Android.view.View;
Import Android.view.ViewGroup;
Import Android.widget.BaseAdapter;
Import Android.widget.TextView;
public class Sortadapter extends Baseadapter {private context context;
private list<personbean> persons;
Private Layoutinflater Inflater;
Public Sortadapter (context context, list<personbean> persons) {This.context = context;
this.persons = persons;
This.inflater = Layoutinflater.from (context);
@Override public int GetCount () {//TODO auto-generated a stub return persons.size ();
@Override public Object getitem (int position) {//TODO auto-generated Method stub return Persons.get (position);
@Override public long getitemid (int position) {//TODO auto-generated method stub return position; @Override public View getview (int position, View Convertview, ViewGroup parent) {Viewholder ViewholDer = null;
Personbean person = persons.get (position);
if (Convertview = = null) {Viewholder = new Viewholder ();
Convertview = inflater.inflate (R.layout.list_item, NULL);
Viewholder.tv_tag = (TextView) convertview. Findviewbyid (R.id.tv_lv_item_tag);
Viewholder.tv_name = (TextView) convertview. Findviewbyid (R.id.tv_lv_item_name);
Convertview.settag (Viewholder);
else {Viewholder = (Viewholder) convertview.gettag ();
//Gets the assii value of the first letter int selection = Person.getfirstpinyin (). charAt (0);
The assii value of the first letter is used to determine whether the letter int positionforselection = getpositionforselection (selection) is displayed;
if (position = = Positionforselection) {//Equivalence description needs to display the letter viewholder.tv_tag.setVisibility (view.visible);
Viewholder.tv_tag.setText (Person.getfirstpinyin ());
else {viewholder.tv_tag.setVisibility (view.gone);
} viewholder.tv_name.setText (Person.getname ());
return convertview; public int getpositionforselection (int selection) {to (int i = 0; i < personS.size ();
i++) {String Fpinyin = Persons.get (i). Getfirstpinyin ();
CHAR-i = fpinyin.touppercase (). charAt (0);
if (A/= Selection) {return i;
}} return-1;
Class Viewholder {TextView tv_tag;
TextView Tv_name; }
}
Although not complete, but the more important code has been posted up, I hope to help you