前言:关于这个快速检索我们平常见到的app应用的很多,比如手机通讯录联系人、微信朋友,以及其他的商品列表等,实现的功能就是通过右侧或者左侧的字母进行快速检测,OK!今天我就带领大家来实现这个功能!

--------------------------------分割线--------------------------

首先看一下效果图:

--------------------------------分割线--------------------------

组成:1.右边是自定义QuickIndexBar(重点实现这个自定义控件);

2.左边是listview,它根据当前触摸的字母,去自己列表找首字母和触摸字母相同的那个item,然后让item放置到屏幕顶端(setSelection(position));

3.需要用到获取汉字的拼音,借助类库pinyin4j.jar实现;

4.动画效果,我们使用的是第三方jar包NineOldAndroid;

--------------------------------分割线--------------------------

一:实现自定义QuickIndexBar:

1.继承自View,实现里面的构造方法。

2.在init里面初始化画笔。

3.在onSizeChanged里面可以得到view的width,即可在onDraw里面绘制文本x坐标:width/2。

4.格子高度:view的总高度除以26个字母。

5.绘制文本y坐标:格子高度的一半 + 文本高度的一半 + position*格子高度。

6.计算触摸点对应的字母:根据触摸点的y坐标除以cellHeight,得到的值就是字母对应的索引。

7.当然了我们要设置一个接口,触摸字母的监听器,把触摸的字母回调给我们的监听者。

代码实现:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;/*** Created by Fly on 2017/5/29.*/public class QuickIndexBar extends View {private String[] indexArr = {"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 Paint paint;private int width;private float cellHeight;public QuickIndexBar(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}public QuickIndexBar(Context context, AttributeSet attrs) {super(context, attrs);init();}public QuickIndexBar(Context context) {super(context);init();}private void init() {paint = new Paint(Paint.ANTI_ALIAS_FLAG);//设置抗锯齿paint.setColor(Color.WHITE);paint.setTextSize(16);paint.setTextAlign(Paint.Align.CENTER);//设置文本的起点是文字边框底边的中心}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);width = getMeasuredWidth();//得到一个格子的高度cellHeight = getMeasuredHeight() * 1f / indexArr.length;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);for (int i = 0; i < indexArr.length; i++) {float x = width / 2;float y = cellHeight / 2 + getTextHeight(indexArr[i]) / 2 + i * cellHeight;paint.setColor(lastIndex == i ? Color.BLACK : Color.WHITE);canvas.drawText(indexArr[i], x, y, paint);}}private int lastIndex = -1;//记录上次的触摸字母的索引@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_MOVE:float y = event.getY();int index = (int) (y / cellHeight);//得到字母对应的索引if (lastIndex != index) {//说明当前触摸字母和上一个不是同一个字母
//              Log.e("tag", indexArr[index]);//对index做安全性的检查if (index >= 0 && index < indexArr.length) {if (listener != null) {listener.onTouchLetter(indexArr[index]);}}}lastIndex = index;break;case MotionEvent.ACTION_UP://重置lastIndexlastIndex = -1;break;}//引起重绘invalidate();return true;}/*** 获取文本的高度** @param text* @return*/private int getTextHeight(String text) {//获取文本的高度Rect bounds = new Rect();paint.getTextBounds(text, 0, text.length(), bounds);return bounds.height();}private OnTouchLetterListener listener;public void setOnTouchLetterListener(OnTouchLetterListener listener) {this.listener = listener;}/*** 触摸字母的监听器** @author Administrator*/public interface OnTouchLetterListener {void onTouchLetter(String letter);}}

二:然后在MainActivity中设置Letter的监听:

quickIndexBar.setOnTouchLetterListener(new QuickIndexBar.OnTouchLetterListener() {@Overridepublic void onTouchLetter(String letter) {//根据当前触摸的字母,去集合中找那个item的首字母和letter一样,然后将对应的item放到屏幕顶端for (int i = 0; i < friends.size(); i++) {String firstWord = friends.get(i).getPinyin().charAt(0) + "";if (letter.equals(firstWord)) {//说明找到了,那么应该讲当前的item放到屏幕顶端listview.setSelection(i);break;//只需要找到第一个就行}}//显示当前触摸的字母showCurrentWord(letter);}});

显示当前触摸的字母,这里我们可以加入动画效果,当然也可以在这里用handler进行延时隐藏文本(完整代码给出的有)。

protected void showCurrentWord(String letter) {currentWord.setText(letter);if (!isScale) {isScale = true;ViewPropertyAnimator.animate(currentWord).scaleX(1f).setInterpolator(new OvershootInterpolator()).setDuration(450).start();ViewPropertyAnimator.animate(currentWord).scaleY(1f).setInterpolator(new OvershootInterpolator()).setDuration(450).start();}}

三:关于如何文字转换成拼音。

实现思路:我们可以在ArrayList的泛型中定义name和pinyin两个字符串,然后在javaBean里完成name对拼音的转换。

JavaBean代码:

public class Friend implements Comparable<Friend>{private String name;private String pinyin;//使用成员变量生成构造方法:alt+shift+s->opublic Friend(String name) {super();this.name = name;//一开始就转化好拼音setPinyin(PinYinUtil.getPinyin(name));}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic int compareTo(Friend another) {return getPinyin().compareTo(another.getPinyin());}public String getPinyin() {return pinyin;}public void setPinyin(String pinyin) {this.pinyin = pinyin;}}

拼音工具类的实现是在第三方类库pinyin4j.jar的基础上进行封装,封装实现代码:

import android.text.TextUtils;
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;/*** Created by Fly on 2017/5/29.*/public class PinYinUtil {/*** 获取汉字的拼音,会销毁一定的资源,所以不应该被频繁调用* @param chinese* @return*/public static String getPinyin(String chinese){if(TextUtils.isEmpty(chinese)) return null;//用来设置转化的拼音的大小写,或者声调HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();format.setCaseType(HanyuPinyinCaseType.UPPERCASE);//设置转化的拼音是大写字母format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);//设置转化的拼音不带声调//1.由于只能对单个汉字转化,所以需要将字符串转化为字符数组,然后对每个字符转化,最后拼接起来char[] charArray = chinese.toCharArray();String pinyin = "";for (int i = 0; i < charArray.length; i++) {//2.过滤空格if(Character.isWhitespace(charArray[i]))continue;//3.需要判断是否是汉字//汉字占2个字节,一个字节范围是-128~127,那么汉字肯定大于127if(charArray[i]>127){//可能是汉字try {//由于多音字的存在,比如单  dan shan,String[] pinyinArr = PinyinHelper.toHanyuPinyinStringArray(charArray[i],format);if(pinyinArr!=null){pinyin += pinyinArr[0];//此处即使有多音字,那么也只能取第一个拼音}else {//说明没有找到对应的拼音,汉字有问题,或者可能不是汉字,则忽略}} catch (BadHanyuPinyinOutputFormatCombination e) {e.printStackTrace();//说明转化失败,不是汉字,比如O(∩_∩)O~,那么则忽略}}else {//肯定不是汉字,应该是键盘上能够直接输入的字符,这些字符能够排序,但不能获取拼音//所以可以直接拼接  a黑马->aheimapinyin += charArray[i];}}return pinyin;}
}

--------------------------------完整代码下载--------------------------

完整代码以及第三方类库pinyin4j.jar下载:Android自定义控件之实现快速检索代码

Android自定义控件之实现快速检索相关推荐

  1. 自定义android控件:快速检索QuickSearch

    文章目录 上效果图 逻辑骨架 赋予UI UI封装 quick_search_layout.xml item_ordered_list.xml 使用 Android有自带的下拉选择控件Spinner.问 ...

  2. 虹软人脸识别SDK接入Milvus实现海量人脸快速检索

    虹软人脸识别SDK接入Milvus实现海量人脸快速检索 背景 虹软SDK及Milvus简介 开发环境 虹软人脸识别SDK使用简介 Milvus环境搭建 快速检索实现 人脸识别流程简介 快速检索 虹软S ...

  3. android 联系人 中文 排序,Android中文联系人排序及检索补丁的原理

    Android中文联系人排序及检索补丁的原理(090819更新) 2009年4月26日,更新了源码和相关文件 很久以前做了这个补丁,有幸的是朋友们都还算喜爱它,没白费功夫.不少朋友来信问它的原理,现在 ...

  4. Android中文联系人排序及检索补丁的原理(090819更新)

    原文转自孙志岗老师Sunner的博客:http://blog.sunner.cn/2009/04/android_pinyin_sorting/ 文章写的是针对Android1.0, 1.1及1.5( ...

  5. Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

    Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

  6. Elasticsearch 如何做到快速检索 - 倒排索引的秘密

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:https://ricstudio.top/archives/es-lucene-reverted-index 一.前言 最近 ...

  7. android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...

    转载:http://blog.csdn.net/xiabing082/article/details/48781489 1.  大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...

  8. Elasticsearch 为什么能做到快速检索?— 倒排索引的秘密

    来源:https://ricstudio.top/archives/es-lucene-reverted-index "All problems in computer science ca ...

  9. Elasticsearch 如何做到快速检索?

    " 最近接触的几个项目都使用到了 Elasticsearch (以下简称 ES ) 来存储数据和对数据进行搜索分析,就对 ES 进行了一些学习.本文整理自我自己的一次技术分享. 本文不会关注 ...

最新文章

  1. 基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(一)
  2. sqlserver 类似oracle的rownum功能: row_number
  3. 有赞统一日志平台初探
  4. 15个著名的设计心理学原理以及在设计中的应用
  5. ElasticSearch-6.3.2 linux 安装
  6. angularjs中按回车事件_浅谈angularjs中响应回车事件
  7. java当中的定时器的4种使用方式
  8. asp 文本转时间_[译]使用LazZiya.ExpressLocalization开发多语言支持的ASP.NET Core 2.x项目...
  9. Eclipse SVN提交代码ClientException异常解决
  10. DIY一款600元成本的电路板热成像故障分析仪
  11. WIN10虚拟机安装教程
  12. 银行争夺又一万亿市场:汽车金融
  13. 300秒就完成第一超算1万年的计算量,量子霸权真时代要来了吗
  14. [转] volatile关键字解析
  15. opencv python gpu加速_OpenCV中配置CUDA,实现GPU加速
  16. python 梳理:安装并开始使用
  17. 读书笔记 来自网络
  18. 为什么你的抖音号涨粉慢,粉丝上不去的关键原因
  19. win10+Ubantu双系统
  20. HMaster节点无故挂掉

热门文章

  1. python,你也和小猪佩奇一样社会了!
  2. 信捷原创程序,8个伺服轴。 PLC:信捷XDM-60T10 HMI:信捷TG765 总体I/O在200个点之内
  3. OSChina 周二乱弹 ——程序员在聊天中注意观察什么细节
  4. 2.6 Photoshop操作步骤的撤消和重做 [Ps教程]
  5. 【AP5904】三功能 2.5-5V 1.8A LED车灯 手电筒驱动芯片
  6. 《用户行为画像》学习(1-4章)
  7. 近日,南大通用合作伙伴大会隆重召开……
  8. 能自我学习的AI 能辨识20种乐器声音
  9. 红外遥控器添加遥控支持方法
  10. ElementUI的表格换行符失效、不换行