联系人排序java代码_Android仿微信联系人按字母排序_脚本之家
App只要涉及到聯(lián)系人的界面,幾乎都是按照字母排序以及導(dǎo)航欄的方式。既然這個(gè)需求這么火,于是開始學(xué)習(xí)相關(guān)內(nèi)容,此篇文章是我通過參考網(wǎng)上資料獨(dú)立編寫和總結(jié)的,希望多多少少對大家有所幫助,寫的不好,還請各位朋友指教。
效果圖如下:
實(shí)現(xiàn)這個(gè)效果,需要三個(gè)知識點(diǎn) :1:將字符串 進(jìn)行拼音分類
2:ExpandableListView 二級擴(kuò)展列表
3:右邊字母分類View
我們先一個(gè)一個(gè)來了解解決方案,再上代碼。
實(shí)現(xiàn)字母分類:
字母分類又分為三個(gè)小要點(diǎn):一個(gè)是將中文轉(zhuǎn)化為拼音,一個(gè)是實(shí)現(xiàn)按照字母的順序排序,另一個(gè)是字母只顯示在具有相同首字母中文的第一個(gè)前面。
1、將中文轉(zhuǎn)化為拼音,這里使用了一個(gè)工具包,即pinyin4j-2.5.0.jar。官網(wǎng)地址:http://pinyin4j.sourceforge.net/點(diǎn)擊下載,導(dǎo)入項(xiàng)目即可。(至于教程,網(wǎng)上很多)
在這里我們只需要使用將中文轉(zhuǎn)換成拼音的代碼即可。
PinyinUtils.javapublic 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、實(shí)現(xiàn)按照字母的順序排序,使用的是JAVA自帶的Comparator接口,利用之前獲取到的中文拼音,得到首字母并根據(jù)ascii值來實(shí)現(xiàn)排序。
private int sort(PersonBean lhs, PersonBean rhs) { // 獲取ascii值 int lhs_ascii = lhs.getFirstPinYin().toUpperCase().charAt(0); int rhs_ascii = rhs.getFirstPinYin().toUpperCase().charAt(0); // 判斷若不是字母,則排在字母之后 if (lhs_ascii < 65="" ||="" lhs_ascii=""> 90) return 1; else if (rhs_ascii < 65="" ||="" rhs_ascii=""> 90) return -1; else return lhs.getPinYin().compareTo(rhs.getPinYin()); }
3、字母只顯示在具有相同首字母中文的第一個(gè)前面。這里算是一個(gè)小技巧,這里字母顯示的布局與中文名字的布局都是存放在ListView的item的布局中的。
item的布局如下:
而判斷是否需要顯示字母,是通過判斷當(dāng)前item的position是否等于第一個(gè)出現(xiàn)item對應(yīng)的中文首字母的索引。
如果相等,則說明是第一次出現(xiàn),便需要顯示字母,否則不顯示字母。而這樣的判斷,有一個(gè)前提,那就是中文拼音的排序必須是按照字母順序排序的,這就是我們在上一步排序的必要。
實(shí)現(xiàn)右側(cè)的字母導(dǎo)航:
右側(cè)的字母導(dǎo)航,其本質(zhì)就是一個(gè)自定義View。除了繪制界面之外,需要注意的就是觸摸事件的處理,還有回調(diào)機(jī)制(這個(gè)很多地方都會(huì)用到)的使用。這個(gè)比較重要,直接上代碼吧。
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 { // 觸摸事件 private OnTouchingLetterChangedListener onTouchingLetterChangedListener; // 26個(gè)字母 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;// 選中 private Paint paint = new Paint(); private TextView mTextDialog; /** * 為SideBar設(shè)置顯示字母的TextView * @param mTextDialog */ public void setTextView(TextView mTextDialog) { this.mTextDialog = mTextDialog; } public SideBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public SideBar(Context context, AttributeSet attrs) { super(context, attrs); } public SideBar(Context context) { super(context); } /** * 重寫這個(gè)方法 */ protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 獲取焦點(diǎn)改變背景顏色. int height = getHeight();// 獲取對應(yīng)高度 int width = getWidth(); // 獲取對應(yīng)寬度 int singleHeight = height / A_Z.length-2;// 獲取每一個(gè)字母的高度 (這里-2僅僅是為了好看而已) for (int i = 0; i < a_z.length;="" i++)="" {="" paint.setcolor(color.rgb(33,="" 65,="" 98));="" 設(shè)置字體顏色="" paint.settypeface(typeface.default_bold);="" 設(shè)置字體="" paint.setantialias(true);="" 設(shè)置抗鋸齒="" paint.settextsize(30);="" 設(shè)置字母字體大小="" 選中的狀態(tài)="" if="" (i="=" choose)="" {="" paint.setcolor(color.parsecolor('#3399ff'));="" 選中的字母改變顏色="" paint.setfakeboldtext(true);="" 設(shè)置字體為粗體="" }="" x坐標(biāo)等于中間-字符串寬度的一半.="" float="" xpos="width" 2="" -="" paint.measuretext(a_z[i])="" 2;="" float="" ypos="singleHeight" *="" i="" +="" singleheight;="" canvas.drawtext(a_z[i],="" xpos,="" ypos,="" paint);="" 繪制所有的字母="" paint.reset();//="" 重置畫筆="" }="" }="" @override="" public="" boolean="" dispatchtouchevent(motionevent="" event)="" {="" final="" int="" action="event.getAction();" final="" float="" y="event.getY();//" 點(diǎn)擊y坐標(biāo)="" final="" int="" oldchoose="choose;" final="" ontouchingletterchangedlistener="" listener="onTouchingLetterChangedListener;" final="" int="" c="(int)" (y="" getheight()="" *="" a_z.length);//="" 點(diǎn)擊y坐標(biāo)所占總高度的比例*b數(shù)組的長度就等于點(diǎn)擊b中的個(gè)數(shù).="" 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)" {="" 判斷選中字母是否發(fā)生改變="" 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;="" }="" *="" *="" 向外公開的方法="" *="" *="" @param="" ontouchingletterchangedlistener="" */="" public="" void="" setontouchingletterchangedlistener(="" ontouchingletterchangedlistener="" ontouchingletterchangedlistener)="" {="" this.ontouchingletterchangedlistener="onTouchingLetterChangedListener;" }="" *="" *="" 接口="" *="" *="" @author="" coder="" *="" */="" public="" interface="" ontouchingletterchangedlistener="" {="" public="" void="" ontouchingletterchanged(string="" s);="">
接下來就是MainActivity和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(這里用一句話描述這個(gè)類的作用) * @author 銀色的流星 歡迎批評、指導(dǎo)、交流 QQ:962455668 */public class MainActivity extends Activity { private ListView listView; private SortAdapter sortadapter; private Listdata; private SideBar sidebar; private TextView dialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } private ListgetData(String[] data) { Listlistarray = new ArrayList(); 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);="" 正則表達(dá)式,判斷首字母是否是英文字母="" 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);="" 設(shè)置字母導(dǎo)航觸摸監(jiān)聽="" sidebar.setontouchingletterchangedlistener(new="" ontouchingletterchangedlistener()="" {="" @override="" public="" void="" ontouchingletterchanged(string="" s)="" {="" todo="" auto-generated="" method="" stub="" 該字母首次出現(xiàn)的位置="" int="" position="sortadapter.getPositionForSelection(s.charAt(0));" if="" (position="" !="-1)" {="" listview.setselection(position);="" }="" }="" });="" data="getData(getResources().getStringArray(R.array.listpersons));" 數(shù)據(jù)在放在adapter之前需要排序="" collections.sort(data,="" 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 Listpersons; private LayoutInflater inflater; public SortAdapter(Context context, Listpersons) { this.context = context; this.persons = persons; this.inflater = LayoutInflater.from(context); } @Override public int getCount() { // TODO Auto-generated method 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(); } // 獲取首字母的assii值 int selection = person.getFirstPinYin().charAt(0); // 通過首字母的assii值來判斷是否顯示字母 int positionForSelection = getPositionForSelection(selection); if (position == positionForSelection) {// 相等說明需要顯示字母 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) { for (int i = 0; i < persons.size();="" i++)="" {="" string="" fpinyin="persons.get(i).getFirstPinYin();" char="" first="Fpinyin.toUpperCase().charAt(0);" if="" (first="=" selection)="" {="" return="" i;="" }="" }="" return="" -1;="" }="" class="" viewholder="" {="" textview="" tv_tag;="" textview="" tv_name;="">
雖然不全,但比較重要的代碼都已經(jīng)貼上去了,希望對大家有所幫助
總結(jié)
以上是生活随笔為你收集整理的联系人排序java代码_Android仿微信联系人按字母排序_脚本之家的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java泛型机制的好处_java 泛型机
- 下一篇: midi api java_Java声音