zoukankan      html  css  js  c++  java
  • 快速索引

    如下是快速索引的效果图,是从网上下的实例。如图实现的难点1:是最右侧的索引是用自定义View来实现的,主要通过onDraw的方法将其画出;

    难点2:是如何拿到每个名字的首字母用的是pinyin4j-2.5.0.jar  将汉字转化成拼音再去第一个字符;难点3:ListView的adapte不好实现

    下图的布局是一个ListView右侧是一个自定义的View,中间是一个TextView点击的时候显示

                                  

    如下是自定义的View来实现快速索引

      1 package com.demo.sb.widget;
      2 
      3 import android.content.Context;
      4 import android.graphics.Canvas;
      5 import android.graphics.Color;
      6 import android.graphics.Paint;
      7 import android.graphics.Rect;
      8 import android.graphics.Typeface;
      9 import android.util.AttributeSet;
     10 import android.util.Log;
     11 import android.view.MotionEvent;
     12 import android.view.View;
     13 
     14 /**
     15  * 快速索引 用于根据字母快速定位联系人 也就是界面最右边的那个红色竖条
     16  * 
     17  * @author Administrator
     18  * 
     19  */
     20 public class QuickIndexBar extends View {
     21 
     22     private static final String[] LETTERS = new String[] { "A", "B", "C", "D",
     23             "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
     24             "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
     25 
     26     private Paint mPaint;
     27 
     28     private float cellHeight;
     29 
     30     private int cellWidth;
     31 
     32     /**
     33      * 暴露一个字母的监听
     34      */
     35     public interface OnLetterUpdateListener {
     36         void onLetterUpdate(String letter);
     37     }
     38 
     39     private OnLetterUpdateListener listener;
     40 
     41     public OnLetterUpdateListener getListener() {
     42         return listener;
     43     }
     44 
     45     /**
     46      * 设置字母更新的监听
     47      */
     48     public void setListener(OnLetterUpdateListener listener) {
     49         this.listener = listener;
     50     }
     51 
     52     public QuickIndexBar(Context context) {
     53         this(context, null);
     54         // TODO Auto-generated constructor stub
     55     }
     56 
     57     public QuickIndexBar(Context context, AttributeSet attrs) {
     58         this(context, attrs, 0);
     59         // TODO Auto-generated constructor stub
     60     }
     61 
     62     public QuickIndexBar(Context context, AttributeSet attrs, int defStyleAttr) {
     63         super(context, attrs, defStyleAttr);
     64         mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     65         mPaint.setColor(Color.WHITE);
     66         mPaint.setTypeface(Typeface.DEFAULT_BOLD);
     67     }
     68 
     69     @Override
     70     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
     71         // TODO Auto-generated method stub
     72         super.onSizeChanged(w, h, oldw, oldh);
     73         cellWidth = getMeasuredWidth();
     74 
     75         int mHeight = getMeasuredHeight();
     76         cellHeight = mHeight * 1.0f / LETTERS.length;
     77     }
     78 
     79     /**
     80      * 绘制自定义最重要的一步重写onDraw方法 画什么,由Canvas处理 怎么画,由Paint处理
     81      */
     82     @Override
     83     protected void onDraw(Canvas canvas) {
     84         // TODO Auto-generated method stub
     85         for (int i = 0; i < LETTERS.length; i++) {
     86             String text = LETTERS[i];
     87             // 计算坐标
     88             int x = (int) (cellWidth / 2.0f - mPaint.measureText(text) / 2.0f);
     89             // 获取文本的高度
     90             Rect bounds = new Rect();// 矩形
     91             mPaint.getTextBounds(text, 0, text.length(), bounds);
     92             int textHeight = bounds.height();
     93             int y = (int) (cellHeight / 2.0f + textHeight / 2.0f + i
     94                     * cellHeight);
     95 
     96             // 根据按下的字母,设置画笔颜色
     97             mPaint.setColor(touchIndex == i ? Color.GRAY : Color.WHITE);
     98 
     99             // 绘制文本A-Z
    100             canvas.drawText(text, x, y, mPaint);
    101         }
    102     }
    103 
    104     int touchIndex = -1;
    105 
    106     @Override
    107     public boolean onTouchEvent(MotionEvent event) {
    108         // TODO Auto-generated method stub
    109         int index = -1;
    110         switch (event.getAction()) {
    111         case MotionEvent.ACTION_DOWN:
    112             // 获取当前触摸到的字母索引
    113             index = (int) (event.getY() / cellHeight);
    114             if (index >= 0 && index < LETTERS.length) {
    115                 // 判断是否跟上一次触摸到的一样
    116                 if (index != touchIndex) {
    117 
    118                     if (listener != null) {
    119                         listener.onLetterUpdate(LETTERS[index]);
    120                     }
    121 
    122                     Log.d("jiejie", "onTouchEvent:  " + LETTERS[index]);
    123 
    124                     touchIndex = index;
    125                 }
    126             }
    127             break;
    128         case MotionEvent.ACTION_MOVE:
    129 
    130             index = (int) (event.getY() / cellHeight);
    131             if (index >= 0 && index < LETTERS.length) {
    132                 // 判断是否跟上一次触摸到的一样
    133                 if (index != touchIndex) {
    134 
    135                     if (listener != null) {
    136                         listener.onLetterUpdate(LETTERS[index]);
    137                     }
    138 
    139                     Log.d("jiejie", "onTouchEvent : " + LETTERS[index]);
    140                     touchIndex = index;
    141                 }
    142             }
    143             break;
    144         case MotionEvent.ACTION_UP:
    145             touchIndex = -1;
    146             break;
    147         default:
    148             break;
    149         }
    150         // 重新绘制
    151         invalidate();
    152         return true;
    153     }
    154 }

    主代码和布局文件

      1 package com.demo.sb.main;
      2 
      3 import java.util.ArrayList;
      4 import java.util.Collections;
      5 import com.demo.sb.entity.Cheeses;
      6 import com.demo.sb.entity.HaoHanAdapter;
      7 import com.demo.sb.entity.Person;
      8 import com.demo.sb.utils.DensityUtil;
      9 import com.demo.sb.widget.QuickIndexBar;
     10 import com.demo.sb.widget.QuickIndexBar.OnLetterUpdateListener;
     11 import com.demo.suibian.R;
     12 import android.app.Activity;
     13 import android.os.Bundle;
     14 import android.os.Handler;
     15 import android.text.TextUtils;
     16 import android.view.View;
     17 import android.widget.ListView;
     18 import android.widget.TextView;
     19 
     20 /**
     21  * 快速索引
     22  * 
     23  * @author Administrator
     24  * 
     25  */
     26 public class Activity_Index extends Activity {
     27     
     28     /**ListView用来展示数据的*/
     29     private ListView mListView;
     30     
     31     /**贮存的数据*/
     32     private ArrayList<Person> persons;
     33     
     34     /**展示所点的字母,相当于Toast*/
     35     private TextView tv_center;
     36 
     37     @Override
     38     protected void onCreate(Bundle savedInstanceState) {
     39         // TODO Auto-generated method stub
     40         super.onCreate(savedInstanceState);
     41         setContentView(R.layout.mactivity_index);
     42         
     43         QuickIndexBar bar = (QuickIndexBar) findViewById(R.id.bar);
     44         bar.setListener(new OnLetterUpdateListener() {
     45 
     46             @Override
     47             public void onLetterUpdate(String letter) {
     48                 // TODO Auto-generated method stub
     49                 DensityUtil.showToast(Activity_Index.this, letter);
     50                 showLetter(letter);
     51                 // 根据字母定位ListView,找到集合中第一个以letter为拼音首字母的对象,得到索引
     52                 for (int i = 0; i < persons.size(); i++) {
     53                     Person p = persons.get(i);
     54                     String l = p.getPinyin().charAt(0) + "";
     55                     if (TextUtils.equals(letter, l)) {
     56                         mListView.setSelection(i);
     57                         break;
     58                     }
     59                 }
     60             }
     61         });
     62 
     63         mListView = (ListView) findViewById(R.id.lv_index);
     64         persons = new ArrayList<Person>();
     65         // 填充数据,排序
     66         fillAndSortData(persons);
     67 
     68         mListView.setAdapter(new HaoHanAdapter(Activity_Index.this, persons));
     69 
     70         tv_center = (TextView) findViewById(R.id.tv_center);
     71 
     72     }
     73 
     74     private Handler mHandler = new Handler();
     75 
     76     /**
     77      * 显示字母
     78      * 
     79      * @param letter
     80      */
     81     protected void showLetter(String letter) {
     82         // TODO Auto-generated method stub
     83         tv_center.setVisibility(View.VISIBLE);
     84         tv_center.setText(letter);
     85 
     86         mHandler.removeCallbacksAndMessages(null);
     87         mHandler.postDelayed(new Runnable() {
     88 
     89             @Override
     90             public void run() {
     91                 // TODO Auto-generated method stub
     92                 tv_center.setVisibility(View.GONE);
     93             }
     94         }, 2000);
     95     }
     96 
     97     private void fillAndSortData(ArrayList<Person> persons2) {
     98         // TODO Auto-generated method stub
     99         // 填充数据
    100         for (int i = 0; i < Cheeses.NAMES.length; i++) {
    101             String name = Cheeses.NAMES[i];
    102             persons2.add(new Person(name));
    103         }
    104 
    105         // 进行排序
    106         Collections.sort(persons2);
    107     }
    108 }
     1 <?xml version="1.0" encoding="utf-8"?>
     2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent" >
     5 
     6     <ListView
     7         android:id="@+id/lv_index"
     8         android:layout_width="match_parent"
     9         android:layout_height="match_parent" />
    10 
    11     <com.demo.sb.widget.QuickIndexBar
    12         android:id="@+id/bar"
    13         android:layout_width="30dp"
    14         android:layout_height="match_parent"
    15         android:layout_alignParentRight="true"
    16         android:background="#f00" />
    17 
    18     <TextView
    19         android:id="@+id/tv_center"
    20         android:layout_width="160dp"
    21         android:layout_height="100dp"
    22         android:layout_centerInParent="true"
    23         android:background="@drawable/bg_index"
    24         android:gravity="center"
    25         android:text=""
    26         android:textColor="#fff"
    27         android:textSize="32sp"
    28         android:visibility="gone" />
    29 
    30 </RelativeLayout>

    适配器

     1 package com.demo.sb.entity;
     2 
     3 import java.util.ArrayList;
     4 
     5 import com.demo.sb.utils.DensityUtil;
     6 import com.demo.suibian.R;
     7 
     8 import android.content.Context;
     9 import android.text.TextUtils;
    10 import android.view.View;
    11 import android.view.ViewGroup;
    12 import android.widget.BaseAdapter;
    13 import android.widget.TextView;
    14 
    15 public class HaoHanAdapter extends BaseAdapter {
    16 
    17     private Context mContext;
    18     private ArrayList<Person> persons;
    19 
    20     public HaoHanAdapter(Context mContext, ArrayList<Person> persons) {
    21         this.mContext = mContext;
    22         this.persons = persons;
    23     }
    24 
    25     @Override
    26     public int getCount() {
    27         // TODO Auto-generated method stub
    28         return persons.size();
    29     }
    30 
    31     @Override
    32     public Object getItem(int arg0) {
    33         // TODO Auto-generated method stub
    34         return persons.get(arg0);
    35     }
    36 
    37     @Override
    38     public long getItemId(int arg0) {
    39         // TODO Auto-generated method stub
    40         return arg0;
    41     }
    42 
    43     @Override
    44     public View getView(final int arg0, View arg1, ViewGroup arg2) {
    45         // TODO Auto-generated method stub
    46         ViewHolder holder = null;
    47         if (arg1 == null) {
    48             arg1 = View.inflate(mContext, R.layout.item_haohanadapter, null);
    49             holder = new ViewHolder();
    50             holder.mIndex = (TextView) arg1.findViewById(R.id.item_tv_index);
    51             holder.mName = (TextView) arg1.findViewById(R.id.item_tv_name);
    52             arg1.setTag(holder);
    53         } else {
    54             holder = (ViewHolder) arg1.getTag();
    55         }
    56         
    57         final Person p = persons.get(arg0);
    58         String string = null;
    59         String currentLetter = p.getPinyin().charAt(0) + "";
    60         // 根据上一个首字母,决定当前是否显示字母
    61         if (arg0 == 0) {
    62             string = currentLetter;
    63         } else {
    64             // 上一个人的拼音的首字母
    65             String preLetter = persons.get(arg0 - 1).getPinyin().charAt(0) + "";
    66             if (!TextUtils.equals(preLetter, currentLetter)) {
    67                 string = currentLetter;
    68             }
    69         }
    70 
    71         // 根据string 是否为空,决定是否显示索引栏
    72         holder.mIndex.setVisibility(string == null ? View.GONE : View.VISIBLE);
    73         holder.mIndex.setText(currentLetter);
    74         holder.mName.setText(p.getName());
    75         
    76         holder.mName.setOnClickListener(new View.OnClickListener() {
    77             
    78             @Override
    79             public void onClick(View view) {
    80                 // TODO Auto-generated method stub
    81                 DensityUtil.showToast(mContext, arg0 + "  "+p.getName());
    82             }
    83         });
    84         return arg1;
    85     }
    86 
    87     static class ViewHolder {
    88         TextView mIndex;
    89         TextView mName;
    90     }
    91 }

    实体类

    package com.demo.sb.entity;
    
    import com.demo.sb.utils.PinyinUtils;
    
    public class Person implements Comparable<Person>{
    
        private String name;
        private String pinyin;
        
        public Person(String name){
            super();
            this.name = name;
            this.pinyin = PinyinUtils.getPinyin(name);
        }
        
        
        
        public String getName() {
            return name;
        }
    
    
    
        public void setName(String name) {
            this.name = name;
        }
    
    
    
        public String getPinyin() {
            return pinyin;
        }
    
    
    
        public void setPinyin(String pinyin) {
            this.pinyin = pinyin;
        }
    
    
    
        @Override
        public int compareTo(Person another) {
            // TODO Auto-generated method stub
            return this.pinyin.compareTo(another.getPinyin());
        }
    
        
    
    }
    View Code

    汉字转成拼音

    package com.demo.sb.utils;
    
    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.exception.BadHanyuPinyinOutputFormatCombination;
    
    public class PinyinUtils {
        public static String getPinyin(String str) {
    
            HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
            format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
            format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
    
            StringBuilder sb = new StringBuilder();
    
            char[] charArray = str.toCharArray();
            for (int i = 0; i < charArray.length; i++) {
                char c = charArray[i];
                // 如果是空格, 跳过
                if (Character.isWhitespace(c)) {
                    continue;
                }
                if (c >= -127 && c < 128) {
                    // 肯定不是汉字
                    sb.append(c);
                } else {
                    String s = "";
                    try {
                        // 通过char得到拼音集合. 单 -> dan, shan
                        s = PinyinHelper.toHanyuPinyinStringArray(c, format)[0];
                        sb.append(s);
                    } catch (BadHanyuPinyinOutputFormatCombination e) {
                        e.printStackTrace();
                        sb.append(s);
                    }
                }
            }
    
            return sb.toString();
        }
    }
    View Code
  • 相关阅读:
    [super dealloc]内存释放的先后顺序
    NSString的常用方法
    Xcode开发技巧之code snippets(代码片段)
    关于oc运行时 isa指针详解
    ios快捷键
    自动释放池的使用
    【字典树】统计难题
    数据结构实验之图论五:从起始点到目标点的最短步数(BFS)
    字典树模板
    数据结构实验之串三:KMP应用
  • 原文地址:https://www.cnblogs.com/wangfengdange/p/5193410.html
Copyright © 2011-2022 走看看