Android手机联系人带字母索引的快速查找

作者:非著名程序员 时间:2022-12-03 05:38:13 

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

Android手机联系人带字母索引的快速查找

第一步: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();
 }
}

到这里就完事,非常简单吧!

标签:Android,字母索引,快速查找
0
投稿

猜你喜欢

  • ImportBeanDefinitionRegistrar手动控制BeanDefinition创建注册详解

    2021-11-11 18:49:18
  • Java+TestNG接口自动化入门详解

    2023-11-05 04:37:58
  • java实现抽奖功能解析

    2021-08-29 16:08:21
  • C#使用iTextSharp设置PDF所有页面背景图功能实例

    2021-10-26 02:01:59
  • 实例探究Android应用编写时Fragment的生命周期问题

    2022-12-15 19:57:22
  • Java 程序内部是如何执行的?

    2022-04-29 20:18:36
  • 使用工具类-java精确到小数点后6位

    2021-06-24 20:45:39
  • Kotlin挂起函数原理示例剖析

    2023-11-10 21:52:13
  • Java中的三种标准注解和四种元注解说明

    2022-04-25 05:39:46
  • C#泛型和反射实例解析

    2023-10-04 03:49:02
  • springboot如何通过URL方式访问外部资源

    2022-02-07 01:10:15
  • 基于JAVA文件中获取路径及WEB应用程序获取路径的方法

    2022-08-21 01:26:57
  • maven手动上传jar包示例及图文步骤过程

    2023-11-13 22:10:57
  • Spring Boot分离配置文件的多种方式总结

    2021-08-31 14:43:37
  • 浅谈SpringMVC+Spring3+Hibernate4开发环境搭建

    2023-08-06 13:49:19
  • C# 获取枚举值的简单实例

    2023-09-01 00:13:23
  • Android Studio打包jar及aar包的方法

    2023-06-18 15:59:53
  • Unity实现粒子光效导出成png序列帧

    2023-08-30 21:22:52
  • java数据结构算法稀疏数组示例详解

    2021-09-30 11:47:28
  • Flowable执行完毕的流程查找方法

    2023-01-30 08:53:36
  • asp之家 软件编程 m.aspxhome.com