A-Z排序控件的实现
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                A-Z排序控件的实现
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.                        
                                - 前言
最近項目需要做一個地區(qū)首字母a-z排序的效果,記錄一下自己如何實現(xiàn)的.
先看下效果圖:
- 分析
這種效果自己實現(xiàn)還是第一次;之前見過這種效果:
這些字母都是onDraw畫上去的;只要知道每個字母的left,top,right,bottom就能知道它的具體位置,所以onMeasure方法中要確定每個單元格的寬高.文字排序可以先把漢字轉(zhuǎn)換成拼音,再去比較首字母的順序(特殊地區(qū)特殊處理,比如重慶);
具體看下是如何確定字母的位置:
于是乎,代碼就出來了:
1 public class QuickIndexBar extends View { 2 3 private OnLetterUpdateListener onLetterUpdateListener; 4 5 public interface OnLetterUpdateListener{ 6 void onLetterUpdate(String letter); 7 } 8 9 public OnLetterUpdateListener getOnLetterUpdateListener() { 10 return onLetterUpdateListener; 11 } 12 13 public void setOnLetterUpdateListener( 14 OnLetterUpdateListener onLetterUpdateListener) { 15 this.onLetterUpdateListener = onLetterUpdateListener; 16 } 17 private static final String[] LETTERS = new String[]{ 18 "A", "B", "C", "D", "E", "F", 19 "G", "H", "I", "J", "K", "L", 20 "M", "N", "O", "P", "Q", "R", 21 "S", "T", "U", "V", "W", "X", 22 "Y", "Z" 23 }; 24 25 private Paint paint; 26 27 // 單元格寬度 28 private int cellWidth; 29 30 // 單元格高度 31 private float cellHeight; 32 33 34 public QuickIndexBar(Context context) { 35 this(context, null); 36 } 37 38 public QuickIndexBar(Context context, AttributeSet attrs) { 39 this(context, attrs, 0); 40 } 41 42 public QuickIndexBar(Context context, AttributeSet attrs, int defStyle) { 43 super(context, attrs, defStyle); 44 // 創(chuàng)建一個抗鋸齒的畫筆 45 paint = new Paint(Paint.ANTI_ALIAS_FLAG); 46 // 畫筆文本加粗 47 paint.setTypeface(Typeface.DEFAULT_BOLD); 48 // 顏色 49 paint.setColor(Color.WHITE); 50 } 51 52 @Override 53 protected void onDraw(Canvas canvas) { 54 55 // 遍歷26個英文字母, 計算坐標(biāo), 進行繪制 56 for (int i = 0; i < LETTERS.length; i++) { 57 String letter = LETTERS[i]; 58 59 // 計算x坐標(biāo) 60 float x = cellWidth * 0.5f - paint.measureText(letter) * 0.5f; 61 // 計算y坐標(biāo) 62 Rect bounds = new Rect(); 63 // 獲取文本的矩形區(qū)域 64 paint.getTextBounds(letter, 0, letter.length(), bounds); 65 66 float y = cellHeight * 0.5f + bounds.height() * 0.5f + i * cellHeight; 67 68 // 繪制文本 69 canvas.drawText(letter, x, y, paint); 70 } 71 } 72 private int lastIndex = -1; 73 74 @Override 75 public boolean onTouchEvent(MotionEvent event) { 76 77 float y; 78 int currentIndex; 79 80 switch (event.getAction()) { 81 case MotionEvent.ACTION_DOWN: 82 // 獲取被點擊到的字母索引 83 y = event.getY(); 84 // 根據(jù)y值, 計算當(dāng)前按下的字母位置 85 currentIndex = (int) (y / cellHeight); 86 if(currentIndex != lastIndex){ 87 if(currentIndex >= 0 && currentIndex < LETTERS.length){ 88 String letter = LETTERS[currentIndex]; 89 if(onLetterUpdateListener != null){ 90 onLetterUpdateListener.onLetterUpdate(letter); 91 } 92 System.out.println("letter: " + letter); 93 // 記錄上一次觸摸的字母 94 lastIndex = currentIndex; 95 } 96 } 97 98 break; 99 case MotionEvent.ACTION_MOVE: 100 // 獲取被點擊到的字母索引 101 y = event.getY(); 102 // 根據(jù)y值, 計算當(dāng)前按下的字母位置 103 currentIndex = (int) (y / cellHeight); 104 if(currentIndex != lastIndex){ 105 if(currentIndex >= 0 && currentIndex < LETTERS.length){ 106 String letter = LETTERS[currentIndex]; 107 if(onLetterUpdateListener != null){ 108 onLetterUpdateListener.onLetterUpdate(letter); 109 } 110 System.out.println("letter: " + letter); 111 // 記錄上一次觸摸的字母 112 lastIndex = currentIndex; 113 } 114 } 115 116 break; 117 case MotionEvent.ACTION_UP: 118 lastIndex = -1; 119 break; 120 default: 121 break; 122 } 123 124 return true; 125 } 126 127 @Override 128 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 129 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 130 int mHeight = getMeasuredHeight(); 131 cellWidth = getMeasuredWidth(); 132 cellHeight = mHeight * 1.0f / LETTERS.length; 133 } 134 135 136 137 }這種豎直的簡單快速索引就搞定了,此外還添加了觸摸和點擊的監(jiān)聽
- 實現(xiàn)
再來看下我們要的效果圖那種效果是如何實現(xiàn)的;主要區(qū)別就是字母所在位置和觸摸位置的差異,偷點懶,直接上代碼了:
1 @Override 2 protected void onDraw(Canvas canvas) { 3 4 // 遍歷26個英文字母, 計算坐標(biāo), 進行繪制 5 for (int i = 0; i < LETTERS.length; i++) { 6 String letter = LETTERS[i]; 7 8 // 計算x坐標(biāo) 9 // float x = cellWidth * 0.5f - paint.measureText(letter) * 0.5f; 10 float y = cellHeight * 0.5f + paint.measureText(letter) * 0.5f; 11 // 計算y坐標(biāo) 12 Rect bounds = new Rect(); 13 // 獲取文本的矩形區(qū)域 14 paint.getTextBounds(letter, 0, letter.length(), bounds); 15 16 // float y = cellHeight * 0.5f + bounds.height() * 0.5f + i * cellHeight; 17 float x = cellWidth * 0.5f + bounds.width() * 0.5f + i * cellWidth; 18 // 繪制文本 19 canvas.drawText(letter, x, y, paint); 20 } 21 } 22 23 private int lastIndex = -1; 24 25 @Override 26 public boolean onTouchEvent(MotionEvent event) { 27 28 float x; 29 int currentIndex; 30 31 switch (event.getAction()) { 32 case MotionEvent.ACTION_DOWN: 33 // 獲取被點擊到的字母索引 34 x = event.getX(); 35 // 根據(jù)x值, 計算當(dāng)前按下的字母位置 36 currentIndex = (int) (x / cellWidth); 37 if (currentIndex != lastIndex) { 38 if (currentIndex >= 0 && currentIndex < LETTERS.length) { 39 String letter = LETTERS[currentIndex]; 40 if (onLetterUpdateListener != null) { 41 onLetterUpdateListener.onLetterUpdate(letter); 42 } 43 // 記錄上一次觸摸的字母 44 lastIndex = currentIndex; 45 } 46 } 47 48 break; 49 case MotionEvent.ACTION_MOVE: 50 // 獲取被點擊到的字母索引 51 x = event.getX(); 52 // 根據(jù)y值, 計算當(dāng)前按下的字母位置 53 currentIndex = (int) (x / cellWidth); 54 if (currentIndex != lastIndex) { 55 if (currentIndex >= 0 && currentIndex < LETTERS.length) { 56 String letter = LETTERS[currentIndex]; 57 if (onLetterUpdateListener != null) { 58 onLetterUpdateListener.onLetterUpdate(letter); 59 } 60 // 記錄上一次觸摸的字母 61 lastIndex = currentIndex; 62 } 63 } 64 65 break; 66 case MotionEvent.ACTION_UP: 67 lastIndex = -1; 68 break; 69 default: 70 break; 71 } 72 73 return true; 74 } 75 76 @Override 77 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 78 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 79 int mWidth = getMeasuredWidth(); 80 cellWidth = mWidth * 1.0f / LETTERS.length; 81 cellHeight = getMeasuredHeight(); 82 }可以看到主要區(qū)別就是單元格的寬度和高度相應(yīng)改變了;后面會補充一張計算草圖.
?
轉(zhuǎn)載于:https://www.cnblogs.com/fuyaozhishang/p/7110215.html
總結(jié)
以上是生活随笔為你收集整理的A-Z排序控件的实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Linux下C++ UDP Socket
- 下一篇: 西刺代理python_python爬西刺
