快速索引 (对View的自定义)
快速索引 (对View的自定义)
快速索引应用场景: 微信好友列表, 联系人通讯录, 应用管理, 文件管理等。
快速索引7步曲:
*1. A-Z索引的绘制.
* 2. 处理Touch事件.
* 3. 提供使用监听\回调
* 4. 汉字转换成拼音.
* 5. 进行排序展示.
* 6. 进行分组.
* 7. 将自定义控件和ListView合体.
1.A-Z索引的绘制
protected void onDraw(Canvas canvas) {
for (int i = 0; i < LETTERS.length; i++) {
String text = LETTERS[i];
// 计算坐标
int x = (int) (cellWidth / 2.0f - mPaint.measureText(text) / 2.0f);
// 获取文本的高度
Rect bounds = new Rect();// 矩形
mPaint.getTextBounds(text, 0, text.length(), bounds);
int textHeight = bounds.height();
int y = (int) (cellHeight / 2.0f + textHeight / 2.0f + i * cellHeight);
// 根据按下的字母, 设置画笔颜色
mPaint.setColor(touchIndex == i ? Color.GRAY : Color.WHITE);
// 绘制文本A-Z
canvas.drawText(text, x, y, mPaint);
}
}
2 处理Touch事件
int touchIndex = -1;
@Override
public boolean onTouchEvent(MotionEvent event) {
int index = -1;
switch (MotionEventCompat.getActionMasked(event)) {
case MotionEvent.ACTION_DOWN:
// 获取当前触摸到的字母索引
index = (int) (event.getY() / cellHeight);
if(index >= 0 && index < LETTERS.length){
// 判断是否跟上一次触摸到的一样
if(index != touchIndex) {
if(listener != null){
listener.onLetterUpdate(LETTERS[index]);
}
Log.d(TAG, "onTouchEvent: " + LETTERS[index]);
touchIndex = index;
}
}
break;
case MotionEvent.ACTION_MOVE:
index = (int) (event.getY() / cellHeight);
if(index >= 0 && index < LETTERS.length){
// 判断是否跟上一次触摸到的一样
if(index != touchIndex){
if(listener != null){
listener.onLetterUpdate(LETTERS[index]);
}
Log.d(TAG, "onTouchEvent: " + LETTERS[index]);
touchIndex = index;
}
}
break;
case MotionEvent.ACTION_UP:
touchIndex = -1;
break;
default:
break;
}
invalidate();
return true;
}
3.提供使用监听\回调
QuickIndexBar bar = (QuickIndexBar) findViewById(R.id.bar);
// 设置监听
bar.setListener(new OnLetterUpdateListener() {
......}
4.汉字转换成拼音
开源包:pingyin4j.jar
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();
}
显示字母
protected void showLetter(String letter) {
tv_center.setVisibility(View.VISIBLE);
tv_center.setText(letter);
mHandler.removeCallbacksAndMessages(null);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
tv_center.setVisibility(View.GONE);
}
}, 2000);
}
5.进行排序展示
private void fillAndSortData(ArrayList<Person> persons) {
// 填充数据
for (int i = 0; i < Cheeses.NAMES.length; i++) {
String name = Cheeses.NAMES[i];
persons.add(new Person(name));
}
// 进行排序
Collections.sort(persons);
}
Adapter中:
static class ViewHolder {
TextView mIndex;
TextView mName;
public static ViewHolder getHolder(View view) {
Object tag = view.getTag();
if(tag != null){
return (ViewHolder)tag;
}else {
ViewHolder viewHolder = new ViewHolder();
viewHolder.mIndex = (TextView) view.findViewById(R.id.tv_index);
viewHolder.mName = (TextView) view.findViewById(R.id.tv_name);
view.setTag(viewHolder);
return viewHolder;
}
}
6.进行分组
ViewHolder mViewHolder = ViewHolder.getHolder(view);
Person p = persons.get(position);
String str = null;
String currentLetter = p.getPinyin().charAt(0) + "";
// 根据上一个首字母,决定当前是否显示字母
if(position == 0){
str = currentLetter;
}else {
// 上一个人的拼音的首字母
String preLetter = persons.get(position - 1).getPinyin().charAt(0) + "";
if(!TextUtils.equals(preLetter, currentLetter)){
str = currentLetter;
}
}
// 根据str是否为空,决定是否显示索引栏
mViewHolder.mIndex.setVisibility(str == null ? View.GONE : View.VISIBLE);
mViewHolder.mIndex.setText(currentLetter);
mViewHolder.mName.setText(p.getName());
return view;
7.将自定义控件和ListView结合起来
showLetter(letter);
// 根据字母定位ListView, 找到集合中第一个以letter为拼音首字母的对象,得到索引
for (int i = 0; i < persons.size(); i++) {
Person person = persons.get(i);
String l = person.getPinyin().charAt(0) + "";
if(TextUtils.equals(letter, l)){
// 匹配成功
mMainList.setSelection(i);
break;
}
}
快速索引 (对View的自定义)的更多相关文章
- Android ListView A~Z快速索引(改进版)
上一篇文章虽然实现了ListView 快速索引的效果,但是有一个小小的Bug.这个Bug我在前面也说了,这篇文章就来解决这个Bug. 我研究的时候发现只要showBg值为true,中间的字母就显示,而 ...
- 实现ListView A~Z快速索引
ListView A~Z快速索引这种效果在通信录和城市列表中经常看到,方便用户查找,是一种增加用户体验的好方法. 实现步骤: 1.自定义一个名叫SlideBar 的View. 2.在布局文件中加入这个 ...
- Android-自定义联系人快速索引
效果图: 布局去指定 view.custom.shangguigucustomview.MyCustomIndexView 自定义View对象 <!-- 自定义联系人快速索引 --> &l ...
- 8.快速索引、listview
实现这样的效果 布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ...
- Log4net快速索引参考
官方项目地址:The Apache log4net project 本文内容仅为相关项参考,不进行具体使用讨论 另转载请注明出处 Log4net快速索引参考 Log4net主要有以下三个部件: log ...
- Dialog详解(包括进度条、PopupWindow、自定义view、自定义样式的对话框)
Dialog详解(包括进度条.PopupWindow.自定义view.自定义样式的对话框) Android中提供了多种对话框,在实际应用中我们可能会需要修改这些已有的对话框.本实例就是从实际出发, ...
- Android 快速索引(城市列表和联系人)
最近需要实现一个城市列表的快速索引功能.类似于联系人应用,根据姓名首字母快速索引功能. 要实现这个功能只需要解决两个问题:1.对列表进行分组(具有同一特征),并且能够快速定位到该组的第一项 2.右侧分 ...
- 通过圆形载入View了解自定义View
这是自定义View的第一篇文章,通过制作简单的自定义View来了解自定义View的流程. 自定义View是Android学习和开发中必不可少的一部分.通过自定义View我们可以制作丰富绚丽的控件,自定 ...
- 【大盛】HTC one/M7 ROM 最新本地化OrDroid8.2.6 高级、快速设置 永久root 更多自定义 稳定 流畅
了解更多:点击下载ROM和学习更多 ROM版本 HTC-one_OrDroid8.2.6 ROM作者 雪狼团队·大盛 http://weibo.com/DaShengdd Android版本 Andr ...
随机推荐
- 医疗器械c#上位机开发指引教程
此教程面向的读者:对医疗器械上位机编程有兴趣,或者急需了解医疗器械(尿常规.血液分析.生化.心电.B超等医疗下位仪器)的编程流程.编程细节的程序员. 1.得到仪器协议 当我们需要与医疗器械等下位机数据 ...
- js获取设备
总结了一个JavaScript获取当前终端类型(pc, mobile),操作系统类型,浏览器类型,浏览器版本的小工具. 个人觉得还行,测试过没有问题,能识别ie7以及以上. 1 2 3 4 5 6 7 ...
- 树莓派控制HC-SR04超声波模块测距(新手向+C语言向)
因为作业要求使用c语言代码,这里先附上一段摘自网上的代码 感谢KalaerSun的c语言代码,摘自https://blog.csdn.net/qq_25247589/article/details/6 ...
- UVA - 11997:K Smallest Sums
多路归并 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> ...
- UVA11404:Palindromic Subsequence
回文子串dp,最小字典序的话需要记录一下,注意是string型的,不能只记录一个字符,因为可能出现相等的情况 #include<cstdio> #include<cstdlib> ...
- [Apio2012]dispatching 左偏树
题目描述 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个上级.为保密,同时增 ...
- HDU2108和HDU2036(叉乘)
hdu2108 判断是否为凸边形 判断连续三点的叉乘 若为凸,内角<180:若为凹,内角>180 所以通过正负来判断 #include <iostream> #include ...
- [Noi2014]购票
来自FallDream 的博客,未经允许,请勿转载,谢谢. 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的 ...
- [BZOJ]1005 明明的烦恼(HNOI2008)
BZOJ的第一页果然还是很多裸题啊,小C陆续划水屯些板子. Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间 ...
- SQL Server 连接 MySQL
1.在SQL SERVER服务器上安装MYSQL ODBC驱动; 驱动下载地址:http://dev.mysql.com/downloads/connector/odbc/ 2.安装好后,在管理工具- ...