喜欢另辟蹊径的我,在这里废话不多说了,直接上代码和图片了。

效果图如下:

第一步: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;@Overrideprotected 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]));}}}@Overridepublic void onWindowFocusChanged(boolean hasFocus) {// 在oncreate里面执行下面的代码没反应,因为oncreate里面得到的getHeight=0if (!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() {@Overridepublic 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" ><TextViewandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="列表显示"android:textColor="#000000"android:textSize="16sp" /><FrameLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:background="#ffffff" ><ListViewandroid:id="@+id/listView"android:layout_width="match_parent"android:layout_height="wrap_content"android:cacheColorHint="#00000000"android:fadingEdge="none"android:scrollbars="none" ></ListView><TextViewandroid: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" /><LinearLayoutandroid: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;}@Overridepublic int getCount() {return list.size();}@Overridepublic Object getItem(int position) {return list.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic boolean isEnabled(int position) {// TODO Auto-generated method stubif (list.get(position).getName().length() == 1)// 如果是字母索引return false;// 表示不能点击return super.isEnabled(position);}@Overridepublic 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" ><TextViewandroid: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" ><TextViewandroid: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();}
}

到这里就完事,非常简单吧!喜欢我就关注我哦!

求源码,请关注微信订阅号:smart_android,微信名:非著名程序员,关注成功后,给微信号发送您的邮箱,源码就会发到您的邮箱里。发送格式:发送内容+您的邮箱(内容即为你要的源码内容)

Android学习笔记(三)之带有侧边索引的快速查找(跟带字母索引查找的通讯录差不多)相关推荐

  1. Android学习笔记三

    大神博客(必看)http://blog.csdn.net/huachao1001/article/list/1 1.Android校招笔记 http://huachao1001.github.io/i ...

  2. [OC学习笔记]objc_msgSend(一):方法快速查找

    一.OC runtime运行时 在探索objc_msgSend的时候,我们需要先了解OC的runtime机制. (一)runtime简介 runtime 是 OC底层的一套C/C++的API(引入 & ...

  3. Android学习笔记(三):android画图之paint

    2019独角兽企业重金招聘Python工程师标准>>> * Paint类介绍        *         * Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了 ...

  4. ANDROID 学习笔记(三) UI THREAD AsyncTask 使用

    为什么80%的码农都做不了架构师?>>>    一般获取验证码,用户登录验证,上传头像,获取消息,发消息,评论 都可以使用 1.先上官网实例代码 private class Down ...

  5. Android学习笔记(三)

    ContentProvider简单介绍 ContentProvider是不同应用程序之间进行数据交换的标准API,当一个应用程序须要把自己的数据暴露给其它程序使用时.该应用程序便可通过提供Conten ...

  6. 朱丹老师课程学习笔记:1、信息搜索-全面快速查找全网中你想要的任何信息

    在这个信息量爆炸.知识量剧增的时代,我们都有这样的体会,用搜索引擎搜索任何的关键词都会有上百万的信息量,而其中对我们有价值的信息却是寥寥无几.但我们每个人的时间和经历都是有限的,在这种情况下,如果想要 ...

  7. Android学习笔记:Android基础知识点(不断更新中)

    1.Android学习笔记:OkHttp 2.Android学习笔记:更新UI的方法(UI线程和非UI线程) 3.Android学习笔记:Volley 4.Android学习笔记:Handler 5. ...

  8. Android学习笔记26:图片切换控件ImageSwitcher的使用

    在Windows操作系统中,要查看多张图片,可以通过使用"Windows照片查看器"在"上一张"和"下一张"之间切换,进行多张图片的浏览. ...

  9. MySQL学习笔记(三)查询

    写在前面:本篇为作者自学总结,学习内容为课堂所学和网络学习笔记汇总,对于内容引用部分在文中和文末注明. 文章仅供参考,如需深入了解,请查阅MySQL参考手册.附上下载链接: 链接:https://pa ...

最新文章

  1. 机器学习特征工程之连续变量离散化:聚类法进行分箱
  2. Spring Boot集成持久化Quartz定时任务管理
  3. Spring中的InitializingBean的使用详解
  4. 扩展语法检查(SLIN检查)
  5. 国二c语言操作题评分标准,全国计算机二级C语言操作题题库.doc
  6. fastdfs java上传文件_FastDFS java客户端文件上传demo
  7. rxjs的一个例子:什么是rxjs的OperatorFunction?
  8. ubuntu下动态链接库的编译和使用实例
  9. 详解SSH框架和Redis的整合
  10. BOOTP 与 DHCP
  11. 面试者应向公司问什么问题?
  12. 文字转语音功能,MacOS只需两行代码
  13. 版本 tomcat_Tomcat爆出安全漏洞!Spring Cloud/Boot框架多个版本受影响
  14. Eclipse的汉化
  15. 课程与教学管理系统(CMS):Sakai
  16. 解决无线路由器无法进行账号认证上网的问题
  17. 清华计算机系人工智能学院,CoAI - 清华大学交互式人工智能课题组
  18. LABjs、RequireJS、SeaJS 哪个最好用?为什么?
  19. 335x内核ddr3频率与电压修改
  20. 数据库中存储用户名、密码时如何处理?

热门文章

  1. C练习实例11-15题打卡
  2. python n个list如何组成矩阵_硬核科普系列:用python帮你建立自己的投资组合
  3. flink mysql sink_聊聊flink的sink
  4. SuperMap iServer在不同系统中设置开机自启动--Linux篇
  5. OPC 2.0 DCOM 配置
  6. Spring 源码解析(四):bean的加载
  7. javaSE:基础知识【1】
  8. Android Handler面试总结
  9. 下拉框练习,使用onchange事件
  10. hive中日期格式转换