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


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

    效果图如下:

    第一步:MainActivity的代码如下:

    1. package net.loonggg.test;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.Arrays;  
    5. import java.util.HashMap;  
    6. import java.util.List;  
    7. import java.util.TreeSet;  
    8.   
    9. import android.os.Bundle;  
    10. import android.app.Activity;  
    11. import android.graphics.Color;  
    12. import android.view.MotionEvent;  
    13. import android.view.View;  
    14. import android.view.View.OnTouchListener;  
    15. import android.view.Window;  
    16. import android.widget.LinearLayout;  
    17. import android.widget.ListView;  
    18. import android.widget.TextView;  
    19. import android.widget.LinearLayout.LayoutParams;  
    20.   
    21. public class MainActivity extends Activity {  
    22.     private HashMap<String, Integer> selector;// 存放含有索引字母的位置  
    23.     private LinearLayout layoutIndex;  
    24.     private ListView listView;  
    25.     private TextView tv_show;  
    26.     private ListViewAdapter adapter;  
    27.     private String[] indexStr = { "#""A""B""C""D""E""F""G""H",  
    28.             "I""J""K""L""M""N""O""P""Q""R""S""T""U",  
    29.             "V""W""X""Y""Z" };  
    30.     private List<Person> persons = null;  
    31.     private List<Person> newPersons = new ArrayList<Person>();  
    32.     private int height;// 字体高度  
    33.     private boolean flag = false;  
    34.   
    35.     @Override  
    36.     protected void onCreate(Bundle savedInstanceState) {  
    37.         super.onCreate(savedInstanceState);  
    38.         // 去标题栏  
    39.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
    40.         setContentView(R.layout.activity_main);  
    41.         layoutIndex = (LinearLayout) this.findViewById(R.id.layout);  
    42.         layoutIndex.setBackgroundColor(Color.parseColor("#00ffffff"));  
    43.         listView = (ListView) findViewById(R.id.listView);  
    44.         tv_show = (TextView) findViewById(R.id.tv);  
    45.         tv_show.setVisibility(View.GONE);  
    46.         setData();  
    47.         String[] allNames = sortIndex(persons);  
    48.         sortList(allNames);  
    49.   
    50.         selector = new HashMap<String, Integer>();  
    51.         for (int j = 0; j < indexStr.length; j++) {// 循环字母表,找出newPersons中对应字母的位置  
    52.             for (int i = 0; i < newPersons.size(); i++) {  
    53.                 if (newPersons.get(i).getName().equals(indexStr[j])) {  
    54.                     selector.put(indexStr[j], i);  
    55.                 }  
    56.             }  
    57.   
    58.         }  
    59.         adapter = new ListViewAdapter(this, newPersons);  
    60.         listView.setAdapter(adapter);  
    61.     }  
    62.   
    63.     /** 
    64.      * 重新排序获得一个新的List集合 
    65.      *  
    66.      * @param allNames 
    67.      */  
    68.     private void sortList(String[] allNames) {  
    69.         for (int i = 0; i < allNames.length; i++) {  
    70.             if (allNames[i].length() != 1) {  
    71.                 for (int j = 0; j < persons.size(); j++) {  
    72.                     if (allNames[i].equals(persons.get(j).getPinYinName())) {  
    73.                         Person p = new Person(persons.get(j).getName(), persons  
    74.                                 .get(j).getPinYinName());  
    75.                         newPersons.add(p);  
    76.                     }  
    77.                 }  
    78.             } else {  
    79.                 newPersons.add(new Person(allNames[i]));  
    80.             }  
    81.         }  
    82.     }  
    83.   
    84.     @Override  
    85.     public void onWindowFocusChanged(boolean hasFocus) {  
    86.         // 在oncreate里面执行下面的代码没反应,因为oncreate里面得到的getHeight=0  
    87.         if (!flag) {// 这里为什么要设置个flag进行标记,我这里不先告诉你们,请读者研究,因为这对你们以后的开发有好处  
    88.             height = layoutIndex.getMeasuredHeight() / indexStr.length;  
    89.             getIndexView();  
    90.             flag = true;  
    91.         }  
    92.     }  
    93.   
    94.     /** 
    95.      * 获取排序后的新数据 
    96.      *  
    97.      * @param persons 
    98.      * @return 
    99.      */  
    100.     public String[] sortIndex(List<Person> persons) {  
    101.         TreeSet<String> set = new TreeSet<String>();  
    102.         // 获取初始化数据源中的首字母,添加到set中  
    103.         for (Person person : persons) {  
    104.             set.add(StringHelper.getPinYinHeadChar(person.getName()).substring(  
    105.                     01));  
    106.         }  
    107.         // 新数组的长度为原数据加上set的大小  
    108.         String[] names = new String[persons.size() + set.size()];  
    109.         int i = 0;  
    110.         for (String string : set) {  
    111.             names[i] = string;  
    112.             i++;  
    113.         }  
    114.         String[] pinYinNames = new String[persons.size()];  
    115.         for (int j = 0; j < persons.size(); j++) {  
    116.             persons.get(j).setPinYinName(  
    117.                     StringHelper  
    118.                             .getPingYin(persons.get(j).getName().toString()));  
    119.             pinYinNames[j] = StringHelper.getPingYin(persons.get(j).getName()  
    120.                     .toString());  
    121.         }  
    122.         // 将原数据拷贝到新数据中  
    123.         System.arraycopy(pinYinNames, 0, names, set.size(), pinYinNames.length);  
    124.         // 自动按照首字母排序  
    125.         Arrays.sort(names, String.CASE_INSENSITIVE_ORDER);  
    126.         return names;  
    127.     }  
    128.   
    129.     /** 
    130.      * 绘制索引列表 
    131.      */  
    132.     public void getIndexView() {  
    133.         LinearLayout.LayoutParams params = new LayoutParams(  
    134.                 LayoutParams.WRAP_CONTENT, height);  
    135.         for (int i = 0; i < indexStr.length; i++) {  
    136.             final TextView tv = new TextView(this);  
    137.             tv.setLayoutParams(params);  
    138.             tv.setText(indexStr[i]);  
    139.             tv.setPadding(100100);  
    140.             layoutIndex.addView(tv);  
    141.             layoutIndex.setOnTouchListener(new OnTouchListener() {  
    142.   
    143.                 @Override  
    144.                 public boolean onTouch(View v, MotionEvent event)  
    145.   
    146.                 {  
    147.                     float y = event.getY();  
    148.                     int index = (int) (y / height);  
    149.                     if (index > -1 && index < indexStr.length) {// 防止越界  
    150.                         String key = indexStr[index];  
    151.                         if (selector.containsKey(key)) {  
    152.                             int pos = selector.get(key);  
    153.                             if (listView.getHeaderViewsCount() > 0) {// 防止ListView有标题栏,本例中没有。  
    154.                                 listView.setSelectionFromTop(  
    155.                                         pos + listView.getHeaderViewsCount(), 0);  
    156.                             } else {  
    157.                                 listView.setSelectionFromTop(pos, 0);// 滑动到第一项  
    158.                             }  
    159.                             tv_show.setVisibility(View.VISIBLE);  
    160.                             tv_show.setText(indexStr[index]);  
    161.                         }  
    162.                     }  
    163.                     switch (event.getAction()) {  
    164.                     case MotionEvent.ACTION_DOWN:  
    165.                         layoutIndex.setBackgroundColor(Color  
    166.                                 .parseColor("#606060"));  
    167.                         break;  
    168.   
    169.                     case MotionEvent.ACTION_MOVE:  
    170.   
    171.                         break;  
    172.                     case MotionEvent.ACTION_UP:  
    173.                         layoutIndex.setBackgroundColor(Color  
    174.                                 .parseColor("#00ffffff"));  
    175.                         tv_show.setVisibility(View.GONE);  
    176.                         break;  
    177.                     }  
    178.                     return true;  
    179.                 }  
    180.             });  
    181.         }  
    182.     }  
    183.   
    184.     /** 
    185.      * 设置模拟数据 
    186.      */  
    187.     private void setData() {  
    188.         persons = new ArrayList<Person>();  
    189.         Person p1 = new Person("耿琦");  
    190.         persons.add(p1);  
    191.         Person p2 = new Person("王宝强");  
    192.         persons.add(p2);  
    193.         Person p3 = new Person("柳岩");  
    194.         persons.add(p3);  
    195.         Person p4 = new Person("文章");  
    196.         persons.add(p4);  
    197.         Person p5 = new Person("马伊琍");  
    198.         persons.add(p5);  
    199.         Person p6 = new Person("李晨");  
    200.         persons.add(p6);  
    201.         Person p7 = new Person("张馨予");  
    202.         persons.add(p7);  
    203.         Person p8 = new Person("韩红");  
    204.         persons.add(p8);  
    205.         Person p9 = new Person("韩寒");  
    206.         persons.add(p9);  
    207.         Person p10 = new Person("丹丹");  
    208.         persons.add(p10);  
    209.         Person p11 = new Person("丹凤眼");  
    210.         persons.add(p11);  
    211.         Person p12 = new Person("哈哈");  
    212.         persons.add(p12);  
    213.         Person p13 = new Person("萌萌");  
    214.         persons.add(p13);  
    215.         Person p14 = new Person("蒙混");  
    216.         persons.add(p14);  
    217.         Person p15 = new Person("烟花");  
    218.         persons.add(p15);  
    219.         Person p16 = new Person("眼黑");  
    220.         persons.add(p16);  
    221.         Person p17 = new Person("许三多");  
    222.         persons.add(p17);  
    223.         Person p18 = new Person("程咬金");  
    224.         persons.add(p18);  
    225.         Person p19 = new Person("程哈哈");  
    226.         persons.add(p19);  
    227.         Person p20 = new Person("爱死你");  
    228.         persons.add(p20);  
    229.         Person p21 = new Person("阿莱");  
    230.         persons.add(p21);  
    231.   
    232.     }  
    233.   
    234. }  

    此Activity的布局文件如下:
    1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     android:layout_width="fill_parent"  
    3.     android:layout_height="match_parent"  
    4.     android:background="#ffffff"  
    5.     android:orientation="vertical" >  
    6.   
    7.     <TextView  
    8.         android:layout_width="fill_parent"  
    9.         android:layout_height="wrap_content"  
    10.         android:padding="10dp"  
    11.         android:text="列表显示"  
    12.         android:textColor="#000000"  
    13.         android:textSize="16sp" />  
    14.   
    15.     <FrameLayout  
    16.         android:layout_width="match_parent"  
    17.         android:layout_height="match_parent"  
    18.         android:background="#ffffff" >  
    19.   
    20.         <ListView  
    21.             android:id="@+id/listView"  
    22.             android:layout_width="match_parent"  
    23.             android:layout_height="wrap_content"  
    24.             android:cacheColorHint="#00000000"  
    25.             android:fadingEdge="none"  
    26.             android:scrollbars="none" >  
    27.         </ListView>  
    28.   
    29.         <TextView  
    30.             android:id="@+id/tv"  
    31.             android:layout_width="60dp"  
    32.             android:layout_height="60dp"  
    33.             android:layout_gravity="center"  
    34.             android:background="#f0606060"  
    35.             android:gravity="center"  
    36.             android:text="A"  
    37.             android:textColor="#ffffff"  
    38.             android:textSize="30sp" />  
    39.   
    40.         <LinearLayout  
    41.             android:id="@+id/layout"  
    42.             android:layout_width="wrap_content"  
    43.             android:layout_height="fill_parent"  
    44.             android:layout_gravity="right"  
    45.             android:background="#d7d7d7"  
    46.             android:gravity="center"  
    47.             android:orientation="vertical" >  
    48.         </LinearLayout>  
    49.     </FrameLayout>  
    50.   
    51. </LinearLayout>  

    第二步:自定义了一个Adapter,代码如下:
    1. package net.loonggg.test;  
    2.   
    3. import java.util.List;  
    4.   
    5. import android.content.Context;  
    6. import android.view.LayoutInflater;  
    7. import android.view.View;  
    8. import android.view.ViewGroup;  
    9. import android.widget.BaseAdapter;  
    10. import android.widget.TextView;  
    11.   
    12. public class ListViewAdapter extends BaseAdapter {  
    13.     private Context context;  
    14.     private List<Person> list;  
    15.     private ViewHolder viewHolder;  
    16.   
    17.     public ListViewAdapter(Context context, List<Person> list) {  
    18.         this.context = context;  
    19.         this.list = list;  
    20.     }  
    21.   
    22.     @Override  
    23.     public int getCount() {  
    24.         return list.size();  
    25.     }  
    26.   
    27.     @Override  
    28.     public Object getItem(int position) {  
    29.         return list.get(position);  
    30.     }  
    31.   
    32.     @Override  
    33.     public long getItemId(int position) {  
    34.         return position;  
    35.     }  
    36.   
    37.     @Override  
    38.     public boolean isEnabled(int position) {  
    39.         // TODO Auto-generated method stub  
    40.         if (list.get(position).getName().length() == 1)// 如果是字母索引  
    41.             return false;// 表示不能点击  
    42.         return super.isEnabled(position);  
    43.     }  
    44.   
    45.     @Override  
    46.     public View getView(int position, View convertView, ViewGroup parent) {  
    47.         String item = list.get(position).getName();  
    48.         viewHolder = new ViewHolder();  
    49.         if (item.length() == 1) {  
    50.             convertView = LayoutInflater.from(context).inflate(R.layout.index,  
    51.                     null);  
    52.             viewHolder.indexTv = (TextView) convertView  
    53.                     .findViewById(R.id.indexTv);  
    54.         } else {  
    55.             convertView = LayoutInflater.from(context).inflate(R.layout.item,  
    56.                     null);  
    57.             viewHolder.itemTv = (TextView) convertView  
    58.                     .findViewById(R.id.itemTv);  
    59.         }  
    60.         if (item.length() == 1) {  
    61.             viewHolder.indexTv.setText(list.get(position).getName());  
    62.         } else {  
    63.             viewHolder.itemTv.setText(list.get(position).getName());  
    64.         }  
    65.         return convertView;  
    66.     }  
    67.   
    68.     private class ViewHolder {  
    69.         private TextView indexTv;  
    70.         private TextView itemTv;  
    71.     }  
    72.   
    73. }  

    第三步:用到的ListView中的子布局文件如下:

    1、index.xml布局文件代码如下:

    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="fill_parent"  
    4.     android:layout_height="wrap_content"  
    5.     android:background="#9c9c9c"  
    6.     android:orientation="vertical"  
    7.     android:paddingBottom="5dp"  
    8.     android:paddingLeft="10dp"  
    9.     android:paddingTop="5dp" >  
    10.   
    11.     <TextView  
    12.         android:id="@+id/indexTv"  
    13.         android:layout_width="wrap_content"  
    14.         android:layout_height="wrap_content"  
    15.         android:textColor="#0f0f0f" />  
    16.   
    17. </LinearLayout>  

    2、item.xml布局文件代码如下:
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="fill_parent"  
    4.     android:layout_height="wrap_content"  
    5.     android:background="#ffffff"  
    6.     android:orientation="vertical"  
    7.     android:paddingBottom="5dp"  
    8.     android:paddingLeft="20dp"  
    9.     android:paddingTop="5dp" >  
    10.   
    11.     <TextView  
    12.         android:id="@+id/itemTv"  
    13.         android:layout_width="wrap_content"  
    14.         android:layout_height="wrap_content"  
    15.         android:textColor="#000000"  
    16.         android:textSize="20sp" />  
    17.   
    18. </LinearLayout>  

    第四步:用到的实体类及工具类如下:

    1、Person.java代码如下:

    1. package net.loonggg.test;  
    2.   
    3. public class Person {  
    4.     private String name;  
    5.     private String pinYinName;  
    6.   
    7.     public Person(String name) {  
    8.         super();  
    9.         this.name = name;  
    10.     }  
    11.   
    12.     public Person(String name, String pinYinName) {  
    13.         super();  
    14.         this.name = name;  
    15.         this.pinYinName = pinYinName;  
    16.     }  
    17.   
    18.     public String getName() {  
    19.         return name;  
    20.     }  
    21.   
    22.     public void setName(String name) {  
    23.         this.name = name;  
    24.     }  
    25.   
    26.     public String getPinYinName() {  
    27.         return pinYinName;  
    28.     }  
    29.   
    30.     public void setPinYinName(String pinYinName) {  
    31.         this.pinYinName = pinYinName;  
    32.     }  
    33.   
    34. }  

    2、工具类代码如下:
    1. package net.loonggg.test;  
    2.   
    3. import net.sourceforge.pinyin4j.PinyinHelper;  
    4. import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;  
    5. import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;  
    6. import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;  
    7. import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;  
    8. import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;  
    9.   
    10. public class StringHelper {  
    11.     /** 
    12.      * 得到 全拼 
    13.      *  
    14.      * @param src 
    15.      * @return 
    16.      */  
    17.     public static String getPingYin(String src) {  
    18.         char[] t1 = null;  
    19.         t1 = src.toCharArray();  
    20.         String[] t2 = new String[t1.length];  
    21.         HanyuPinyinOutputFormat t3 = new HanyuPinyinOutputFormat();  
    22.         t3.setCaseType(HanyuPinyinCaseType.LOWERCASE);  
    23.         t3.setToneType(HanyuPinyinToneType.WITHOUT_TONE);  
    24.         t3.setVCharType(HanyuPinyinVCharType.WITH_V);  
    25.         String t4 = "";  
    26.         int t0 = t1.length;  
    27.         try {  
    28.             for (int i = 0; i < t0; i++) {  
    29.                 // 判断是否为汉字字符  
    30.                 if (java.lang.Character.toString(t1[i]).matches(  
    31.                         "[\u4E00-\u9FA5]+")) {  
    32.                     t2 = PinyinHelper.toHanyuPinyinStringArray(t1[i], t3);  
    33.                     t4 += t2[0];  
    34.                 } else {  
    35.                     t4 += java.lang.Character.toString(t1[i]);  
    36.                 }  
    37.             }  
    38.             return t4;  
    39.         } catch (BadHanyuPinyinOutputFormatCombination e1) {  
    40.             e1.printStackTrace();  
    41.         }  
    42.         return t4;  
    43.     }  
    44.   
    45.     /** 
    46.      * 得到首字母 
    47.      *  
    48.      * @param str 
    49.      * @return 
    50.      */  
    51.     public static String getHeadChar(String str) {  
    52.   
    53.         String convert = "";  
    54.         char word = str.charAt(0);  
    55.         String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);  
    56.         if (pinyinArray != null) {  
    57.             convert += pinyinArray[0].charAt(0);  
    58.         } else {  
    59.             convert += word;  
    60.         }  
    61.         return convert.toUpperCase();  
    62.     }  
    63.       
    64.     /** 
    65.      * 得到中文首字母缩写 
    66.      *  
    67.      * @param str 
    68.      * @return 
    69.      */  
    70.     public static String getPinYinHeadChar(String str) {  
    71.   
    72.         String convert = "";  
    73.         for (int j = 0; j < str.length(); j++) {  
    74.             char word = str.charAt(j);  
    75.             String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);  
    76.             if (pinyinArray != null) {  
    77.                 convert += pinyinArray[0].charAt(0);  
    78.             } else {  
    79.                 convert += word;  
    80.             }  
    81.         }  
    82.         return convert.toUpperCase();  
    83.     }  
    84. }  

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


    非著名程序员可能是东半球最好的技术分享公众号。每天,每周定时推送一些有关移动开发的原创文章和教程,微信号:smart_android。
  • 相关阅读:
    软件需求变更管理
    Flex自定义事件
    Flex基础控件Button
    Ext JS高级程序设计》即将隆重上市(预计上市时间:091115)
    迈向工程硕士
    Flex基础控件ComboBox
    ExtJS 4 Beta 2预览:Ext.Brew包
    ExtJS 4 Grid组件
    REST WebService与SOAP WebService的比较
    Step by Step WebMatrix网站开发之一:Webmatrix安装
  • 原文地址:https://www.cnblogs.com/loonggg/p/3240248.html
Copyright © 2020-2023  润新知