Android手机联系人带字母索引的快速查找
程序员文章站
2024-03-31 12:55:04
喜欢另辟蹊径的我,在这里废话不多说了,直接上代码和图片了。
效果图如下:
第一步:mainactivity的代码如下:
package net.loo...
喜欢另辟蹊径的我,在这里废话不多说了,直接上代码和图片了。
效果图如下:
第一步:mainactivity的代码如下:
package net.loonggg.test; import java.util.arraylist; import java.util.arrays; import java.util.hashmap; import java.util.list; import java.util.treeset; import android.os.bundle; import android.app.activity; import android.graphics.color; import android.view.motionevent; import android.view.view; import android.view.view.ontouchlistener; import android.view.window; import android.widget.linearlayout; import android.widget.listview; import android.widget.textview; import android.widget.linearlayout.layoutparams; public class mainactivity extends activity { private hashmap<string, integer> selector;// 存放含有索引字母的位置 private linearlayout layoutindex; private listview listview; private textview tv_show; private listviewadapter adapter; private string[] indexstr = { "#", "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 list<person> persons = null; private list<person> newpersons = new arraylist<person>(); private int height;// 字体高度 private boolean flag = false; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // 去标题栏 requestwindowfeature(window.feature_no_title); setcontentview(r.layout.activity_main); layoutindex = (linearlayout) this.findviewbyid(r.id.layout); layoutindex.setbackgroundcolor(color.parsecolor("#00ffffff")); listview = (listview) findviewbyid(r.id.listview); tv_show = (textview) findviewbyid(r.id.tv); tv_show.setvisibility(view.gone); setdata(); string[] allnames = sortindex(persons); sortlist(allnames); selector = new hashmap<string, integer>(); for (int j = 0; j < indexstr.length; j++) {// 循环字母表,找出newpersons中对应字母的位置 for (int i = 0; i < newpersons.size(); i++) { if (newpersons.get(i).getname().equals(indexstr[j])) { selector.put(indexstr[j], i); } } } adapter = new listviewadapter(this, newpersons); listview.setadapter(adapter); } /** * 重新排序获得一个新的list集合 * * @param allnames */ private void sortlist(string[] allnames) { for (int i = 0; i < allnames.length; i++) { if (allnames[i].length() != 1) { for (int j = 0; j < persons.size(); j++) { if (allnames[i].equals(persons.get(j).getpinyinname())) { person p = new person(persons.get(j).getname(), persons .get(j).getpinyinname()); newpersons.add(p); } } } else { newpersons.add(new person(allnames[i])); } } } @override public void onwindowfocuschanged(boolean hasfocus) { // 在oncreate里面执行下面的代码没反应,因为oncreate里面得到的getheight=0 if (!flag) {// 这里为什么要设置个flag进行标记,我这里不先告诉你们,请读者研究,因为这对你们以后的开发有好处 height = layoutindex.getmeasuredheight() / indexstr.length; getindexview(); flag = true; } } /** * 获取排序后的新数据 * * @param persons * @return */ public string[] sortindex(list<person> persons) { treeset<string> set = new treeset<string>(); // 获取初始化数据源中的首字母,添加到set中 for (person person : persons) { set.add(stringhelper.getpinyinheadchar(person.getname()).substring( 0, 1)); } // 新数组的长度为原数据加上set的大小 string[] names = new string[persons.size() + set.size()]; int i = 0; for (string string : set) { names[i] = string; i++; } string[] pinyinnames = new string[persons.size()]; for (int j = 0; j < persons.size(); j++) { persons.get(j).setpinyinname( stringhelper .getpingyin(persons.get(j).getname().tostring())); pinyinnames[j] = stringhelper.getpingyin(persons.get(j).getname() .tostring()); } // 将原数据拷贝到新数据中 system.arraycopy(pinyinnames, 0, names, set.size(), pinyinnames.length); // 自动按照首字母排序 arrays.sort(names, string.case_insensitive_order); return names; } /** * 绘制索引列表 */ public void getindexview() { linearlayout.layoutparams params = new layoutparams( layoutparams.wrap_content, height); for (int i = 0; i < indexstr.length; i++) { final textview tv = new textview(this); tv.setlayoutparams(params); tv.settext(indexstr[i]); tv.setpadding(10, 0, 10, 0); layoutindex.addview(tv); layoutindex.setontouchlistener(new ontouchlistener() { @override public boolean ontouch(view v, motionevent event) { float y = event.gety(); int index = (int) (y / height); if (index > -1 && index < indexstr.length) {// 防止越界 string key = indexstr[index]; if (selector.containskey(key)) { int pos = selector.get(key); if (listview.getheaderviewscount() > 0) {// 防止listview有标题栏,本例中没有。 listview.setselectionfromtop( pos + listview.getheaderviewscount(), 0); } else { listview.setselectionfromtop(pos, 0);// 滑动到第一项 } tv_show.setvisibility(view.visible); tv_show.settext(indexstr[index]); } } switch (event.getaction()) { case motionevent.action_down: layoutindex.setbackgroundcolor(color .parsecolor("#606060")); break; case motionevent.action_move: break; case motionevent.action_up: layoutindex.setbackgroundcolor(color .parsecolor("#00ffffff")); tv_show.setvisibility(view.gone); break; } return true; } }); } } /** * 设置模拟数据 */ private void setdata() { persons = new arraylist<person>(); person p1 = new person("耿琦"); persons.add(p1); person p2 = new person("王宝强"); persons.add(p2); person p3 = new person("柳岩"); persons.add(p3); person p4 = new person("文章"); persons.add(p4); person p5 = new person("马伊琍"); persons.add(p5); person p6 = new person("李晨"); persons.add(p6); person p7 = new person("张馨予"); persons.add(p7); person p8 = new person("韩红"); persons.add(p8); person p9 = new person("韩寒"); persons.add(p9); person p10 = new person("丹丹"); persons.add(p10); person p11 = new person("丹凤眼"); persons.add(p11); person p12 = new person("哈哈"); persons.add(p12); person p13 = new person("萌萌"); persons.add(p13); person p14 = new person("蒙混"); persons.add(p14); person p15 = new person("烟花"); persons.add(p15); person p16 = new person("眼黑"); persons.add(p16); person p17 = new person("许三多"); persons.add(p17); person p18 = new person("程咬金"); persons.add(p18); person p19 = new person("程哈哈"); persons.add(p19); person p20 = new person("爱死你"); persons.add(p20); person p21 = new person("阿莱"); persons.add(p21); } }
此activity的布局文件如下:
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="match_parent" android:background="#ffffff" android:orientation="vertical" > <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10dp" android:text="列表显示" android:textcolor="#000000" android:textsize="16sp" /> <framelayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" > <listview android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="wrap_content" android:cachecolorhint="#00000000" android:fadingedge="none" android:scrollbars="none" > </listview> <textview android:id="@+id/tv" android:layout_width="60dp" android:layout_height="60dp" android:layout_gravity="center" android:background="#f0606060" android:gravity="center" android:text="a" android:textcolor="#ffffff" android:textsize="30sp" /> <linearlayout android:id="@+id/layout" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_gravity="right" android:background="#d7d7d7" android:gravity="center" android:orientation="vertical" > </linearlayout> </framelayout> </linearlayout>
第二步:自定义了一个adapter,代码如下:
package net.loonggg.test; 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 listviewadapter extends baseadapter { private context context; private list<person> list; private viewholder viewholder; public listviewadapter(context context, list<person> list) { this.context = context; this.list = list; } @override public int getcount() { return list.size(); } @override public object getitem(int position) { return list.get(position); } @override public long getitemid(int position) { return position; } @override public boolean isenabled(int position) { // todo auto-generated method stub if (list.get(position).getname().length() == 1)// 如果是字母索引 return false;// 表示不能点击 return super.isenabled(position); } @override public view getview(int position, view convertview, viewgroup parent) { string item = list.get(position).getname(); viewholder = new viewholder(); if (item.length() == 1) { convertview = layoutinflater.from(context).inflate(r.layout.index, null); viewholder.indextv = (textview) convertview .findviewbyid(r.id.indextv); } else { convertview = layoutinflater.from(context).inflate(r.layout.item, null); viewholder.itemtv = (textview) convertview .findviewbyid(r.id.itemtv); } if (item.length() == 1) { viewholder.indextv.settext(list.get(position).getname()); } else { viewholder.itemtv.settext(list.get(position).getname()); } return convertview; } private class viewholder { private textview indextv; private textview itemtv; } }
第三步:用到的listview中的子布局文件如下:
1、index.xml布局文件代码如下:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#9c9c9c" android:orientation="vertical" android:paddingbottom="5dp" android:paddingleft="10dp" android:paddingtop="5dp" > <textview android:id="@+id/indextv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textcolor="#0f0f0f" /> </linearlayout>
2、item.xml布局文件代码如下:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#ffffff" android:orientation="vertical" android:paddingbottom="5dp" android:paddingleft="20dp" android:paddingtop="5dp" > <textview android:id="@+id/itemtv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textcolor="#000000" android:textsize="20sp" /> </linearlayout>
第四步:用到的实体类及工具类如下:
1、person.java代码如下:
package net.loonggg.test; public class person { private string name; private string pinyinname; public person(string name) { super(); this.name = name; } public person(string name, string pinyinname) { super(); this.name = name; this.pinyinname = pinyinname; } public string getname() { return name; } public void setname(string name) { this.name = name; } public string getpinyinname() { return pinyinname; } public void setpinyinname(string pinyinname) { this.pinyinname = pinyinname; } }
2、工具类代码如下:
package net.loonggg.test; import net.sourceforge.pinyin4j.pinyinhelper; import net.sourceforge.pinyin4j.format.hanyupinyincasetype; import net.sourceforge.pinyin4j.format.hanyupinyinoutputformat; import net.sourceforge.pinyin4j.format.hanyupinyintonetype; import net.sourceforge.pinyin4j.format.hanyupinyinvchartype; import net.sourceforge.pinyin4j.format.exception.badhanyupinyinoutputformatcombination; public class stringhelper { /** * 得到 全拼 * * @param src * @return */ public static string getpingyin(string src) { char[] t1 = null; t1 = src.tochararray(); string[] t2 = new string[t1.length]; hanyupinyinoutputformat t3 = new hanyupinyinoutputformat(); t3.setcasetype(hanyupinyincasetype.lowercase); t3.settonetype(hanyupinyintonetype.without_tone); t3.setvchartype(hanyupinyinvchartype.with_v); string t4 = ""; int t0 = t1.length; try { for (int i = 0; i < t0; i++) { // 判断是否为汉字字符 if (java.lang.character.tostring(t1[i]).matches( "[\\u4e00-\\u9fa5]+")) { t2 = pinyinhelper.tohanyupinyinstringarray(t1[i], t3); t4 += t2[0]; } else { t4 += java.lang.character.tostring(t1[i]); } } return t4; } catch (badhanyupinyinoutputformatcombination e1) { e1.printstacktrace(); } return t4; } /** * 得到首字母 * * @param str * @return */ public static string getheadchar(string str) { string convert = ""; char word = str.charat(0); string[] pinyinarray = pinyinhelper.tohanyupinyinstringarray(word); if (pinyinarray != null) { convert += pinyinarray[0].charat(0); } else { convert += word; } return convert.touppercase(); } /** * 得到中文首字母缩写 * * @param str * @return */ public static string getpinyinheadchar(string str) { string convert = ""; for (int j = 0; j < str.length(); j++) { char word = str.charat(j); string[] pinyinarray = pinyinhelper.tohanyupinyinstringarray(word); if (pinyinarray != null) { convert += pinyinarray[0].charat(0); } else { convert += word; } } return convert.touppercase(); } }
到这里就完事,非常简单吧!
下一篇: python 性能优化方法小结