快速索引

来源:http://www.cnblogs.com/wangfengdange/archive/2016/02/16/5193410.html
-Advertisement-
Play Games

如下是快速索引的效果圖,是從網上下的實例。如圖實現的難點1:是最右側的索引是用自定義View來實現的,主要通過onDraw的方法將其畫出; 難點2:是如何拿到每個名字的首字母用的是pinyin4j-2.5.0.jar 將漢字轉化成拼音再去第一個字元;難點3:ListView的adapte不好實現 下


如下是快速索引的效果圖,是從網上下的實例。如圖實現的難點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

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這樣一個需求,第三方聯合登陸的頭像和昵稱整體水平居中,如圖: 對於這樣的需求,不能簡單的對包含頭像和昵稱的div使用margin: 0 auto了,因為昵稱的長度是未知的。 solution 1:利用行內元素的padding-left屬性。把圖片絕對定位到padding-left區域內,然後對外層d
  • 捲標 , 屬性名稱 , 簡介 002 <! - - ... - -> 批註 003 <!> 跑馬燈 004 <marquee>...</marquee>普通捲動 005 <marquee behavior=slide>...</marquee>滑動 006 <marquee behavior=scr
  • 編寫好的CSS代碼能提升頁面的渲染速度。本質上,一條規則都沒有引擎解析的最快。MDN上將CSS選擇符歸拆分成四個主要類別,如下所示,性能依次降低。 ID 規則 Class 規則 標簽規則 通用規則 對效率普遍認識是從Steve Souders在2009年出版的《高性能網站建設進階指南》開始的,雖然S
  • 1.DOM:文檔對象模型DOM(Document Object Model)定義訪問和處理HTML文檔的標準方法。DOM 將HTML文檔呈現為帶有元素、屬性和文本的樹結構(節點樹)。 2.DOM的一些常用的屬性 2.1 通過ID獲取元素 (1)語法: document.getElementById(
  • 1.2、目的通過學習本文檔,能夠對jQuery有一個簡單的認識瞭解,清楚JQuery與其他JS框架的不同,掌握jQuery的常用語法、使用技巧及註意事項。二、使用方法在需要使用JQuery的頁面中引入JQuery的js文件即可。例如:<script type="text/javascript" sr
  • 前言:有時候我們需要獲取文件的MIMEType的信息,下麵就介紹關於獲取MIMEType的方法。 1、直接百度搜索關鍵字"MIMEType",你會找到,然後查吧: 2、用代碼獲取文件的MIMEType信息: 1 #import "GetMIMEType.h" 2 3 #import <MobileC
  • 前言:使用NSURLConnection實現文件上傳有點繁瑣。 本文並沒有介紹使用第三方框架上傳文件。 正文: 這裡先提供用於編碼測試的介面:http://120.25.226.186:32812 點擊進去你會發現到下麵: 最好該鏈接用Google瀏覽器打開,因為Google瀏覽器開啟開發者模式用起
  • Android開發,需要連接webservice,之前就想用谷歌提供的jar包,下載地址:http://pan.baidu.com/s/1hqMTUHe 把它下載下來粘貼到libs文件夾下即可: 網上有很多類似的方法,我嘗試了很多都沒有成功,最後發現是我下載的jar包有問題導致我一直卡在哪兒。 首先
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...