上一篇文章虽然实现了ListView 快速索引的效果,但是有一个小小的Bug。这个Bug我在前面也说了,这篇文章就来解决这个Bug。

我研究的时候发现只要showBg值为true,中间的字母就显示,而当showBg 的值为false的时候中间的字母就可以消失。只要SlideBar的状态为ACTION_DOWN和ACTION_MOVE 的时候showBg的值为true,而ACTION_UP的时候showBg的值就为false;

所以根据上面这个特征,我们只要把OnToucheLetterChange()这个回调函数的参数改一下就可以了。改成onTouchLetterChange(boolean isTouched, String s)

boolean类型的参数直接把showBg传过去就可以了。

改进后的代码如下:

  1. package com.folyd.tuan.view;
  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.Typeface;
  8. import android.util.AttributeSet;
  9. import android.view.MotionEvent;
  10. import android.view.View;
  11.  
  12. /**
  13. * 自定义的View,实现ListView A~Z快速索引效果
  14. *
  15. * @author Folyd
  16. *
  17. */
  18. public class SlideBar extends View {
  19. private Paint paint = new Paint();
  20. private OnTouchLetterChangeListenner listenner;
  21. // 是否画出背景
  22. private boolean showBg = false;
  23. // 选中的项
  24. private int choose = -1;
  25. // 准备好的A~Z的字母数组
  26. public static String[] letters = { "#", "A", "B", "C", "D", "E", "F", "G",
  27. "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
  28. "U", "V", "W", "X", "Y", "Z" };
  29.  
  30. // 构造方法
  31. public SlideBar(Context context) {
  32. super(context);
  33. }
  34.  
  35. public SlideBar(Context context, AttributeSet attrs) {
  36. super(context, attrs);
  37. }
  38.  
  39. @Override
  40. protected void onDraw(Canvas canvas) {
  41. super.onDraw(canvas);
  42. // 获取宽和高
  43. int width = getWidth();
  44. int height = getHeight();
  45. // 每个字母的高度
  46. int singleHeight = height / letters.length;
  47. if (showBg) {
  48. // 画出背景
  49. canvas.drawColor(Color.parseColor("#55000000"));
  50. }
  51. // 画字母
  52. for (int i = 0; i < letters.length; i++) {
  53. paint.setColor(Color.BLACK);
  54. // 设置字体格式
  55. paint.setTypeface(Typeface.DEFAULT_BOLD);
  56. paint.setAntiAlias(true);
  57. paint.setTextSize(20f);
  58. // 如果这一项被选中,则换一种颜色画
  59. if (i == choose) {
  60. paint.setColor(Color.parseColor("#F88701"));
  61. paint.setFakeBoldText(true);
  62. }
  63. // 要画的字母的x,y坐标
  64. float posX = width / 2 - paint.measureText(letters[i]) / 2;
  65. float posY = i * singleHeight + singleHeight;
  66. // 画出字母
  67. canvas.drawText(letters[i], posX, posY, paint);
  68. // 重新设置画笔
  69. paint.reset();
  70. }
  71. }
  72.  
  73. /**
  74. * 处理SlideBar的状态
  75. */
  76. @Override
  77. public boolean dispatchTouchEvent(MotionEvent event) {
  78. final float y = event.getY();
  79. // 算出点击的字母的索引
  80. final int index = (int) (y / getHeight() * letters.length);
  81. // 保存上次点击的字母的索引到oldChoose
  82. final int oldChoose = choose;
  83. switch (event.getAction()) {
  84. case MotionEvent.ACTION_DOWN:
  85. showBg = true;
  86. if (oldChoose != index && listenner != null && index > 0
  87. && index < letters.length) {
  88. choose = index;
  89. listenner.onTouchLetterChange(showBg, letters[index]);
  90. invalidate();
  91. }
  92. break;
  93.  
  94. case MotionEvent.ACTION_MOVE:
  95. if (oldChoose != index && listenner != null && index > 0
  96. && index < letters.length) {
  97. choose = index;
  98. listenner.onTouchLetterChange(showBg, letters[index]);
  99. invalidate();
  100. }
  101. break;
  102. case MotionEvent.ACTION_UP:
  103. showBg = false;
  104. choose = -1;
  105. if (listenner != null) {
  106. if (index <= 0) {
  107. listenner.onTouchLetterChange(showBg, "A");
  108. } else if (index > 0 && index < letters.length) {
  109. listenner.onTouchLetterChange(showBg, letters[index]);
  110. } else if (index >= letters.length) {
  111. listenner.onTouchLetterChange(showBg, "Z");
  112. }
  113. }
  114. invalidate();
  115. break;
  116. }
  117. return true;
  118. }
  119.  
  120. /**
  121. * 回调方法,注册监听器
  122. *
  123. * @param listenner
  124. */
  125. public void setOnTouchLetterChangeListenner(
  126. OnTouchLetterChangeListenner listenner) {
  127. this.listenner = listenner;
  128. }
  129.  
  130. /**
  131. * SlideBar 的监听器接口
  132. *
  133. * @author Folyd
  134. *
  135. */
  136. public interface OnTouchLetterChangeListenner {
  137.  
  138. void onTouchLetterChange(boolean isTouched, String s);
  139. }
  140.  
  141. }

Activity中就很容易处理了:

  1. mSlideBar
  2. .setOnTouchLetterChangeListenner(new OnTouchLetterChangeListenner() {
  3.  
  4. @Override
  5. public void onTouchLetterChange(boolean isTouched, String s) {
  6.  
  7. float_letter.setText(s);
  8. if (isTouched) {
  9. float_letter.setVisibility(View.VISIBLE);
  10. } else {
  11. float_letter.postDelayed(new Runnable() {
  12.  
  13. @Override
  14. public void run() {
  15. float_letter.setVisibility(View.GONE);
  16. }
  17. }, 100);
  18. }
  19. int position = array.indexOf(s);
  20. mListView.setSelection(position);
  21. }
  22. });

这样就解决Bug了。哈哈。

Android ListView A~Z快速索引(改进版)的更多相关文章

  1. 实现ListView A~Z快速索引

    ListView A~Z快速索引这种效果在通信录和城市列表中经常看到,方便用户查找,是一种增加用户体验的好方法. 实现步骤: 1.自定义一个名叫SlideBar 的View. 2.在布局文件中加入这个 ...

  2. 8.快速索引、listview

    实现这样的效果 布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ...

  3. Android 快速索引(城市列表和联系人)

    最近需要实现一个城市列表的快速索引功能.类似于联系人应用,根据姓名首字母快速索引功能. 要实现这个功能只需要解决两个问题:1.对列表进行分组(具有同一特征),并且能够快速定位到该组的第一项 2.右侧分 ...

  4. Android-自定义联系人快速索引

    效果图: 布局去指定 view.custom.shangguigucustomview.MyCustomIndexView 自定义View对象 <!-- 自定义联系人快速索引 --> &l ...

  5. [Android分享] 【转帖】Android ListView的A-Z字母排序和过滤搜索功能

      感谢eoe社区的分享   最近看关于Android实现ListView的功能问题,一直都是小伙伴们关心探讨的Android开发问题之一,今天看到有关ListView实现A-Z字母排序和过滤搜索功能 ...

  6. android ListView 九大重要属性详细分析、

    android ListView 九大重要属性详细分析. 1.android ListView 一些重要属性详解,兄弟朋友可以参考一下. 首先是stackFromBottom属性,这只该属性之后你做好 ...

  7. 【腾讯Bugly干货分享】Android ListView与RecyclerView对比浅析--缓存机制

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d3e3ab10c62013697408 作者:黄宁源 一,背景 Recy ...

  8. 【转】android ListView 几个重要属性

    android ListView 几个重要属性 分类: Android2012-03-08 19:25 19324人阅读 评论(5) 收藏 举报 listviewandroid活动javalistnu ...

  9. 实现Android ListView 自动加载更多内容

    研究了几个小时终于实现了Android ListView 自动加载的效果. 说说我是怎样实现的.分享给大家. 1.给ListView增加一个FooterView,调用addFooterView(foo ...

随机推荐

  1. 添加鼠标右键菜单项(EditPlus为例)

    下载Editplus,发现大多是绿色版,这就导致鼠标右键快捷菜单了,使用起来不方面,上网搜集了下资料,解决方法很简单: 首先进入注册表:regedit 然后如图设置新项. 其中editplus是右键菜 ...

  2. CSS之清除浮动

    一.清除浮动的目的. 1.当一个父元素的高度不写或为auto时,而且这个父元素内又有浮动的子元素,那么这时候该父元素的高度将不会自动适应子元素的高度,也可以说高度是0px; 有如下代码: <di ...

  3. HTML5学习摘录

    设计原理 不是规范里都包含什么,而是规范里为什么会包含它们,以及在设计这个规范的时候,设计者们是怎么看待这些东西的. 发展史:HTML2.0——>HTML3.2——>HTML4.0.1—— ...

  4. poj 1001 求高精度幂

    本题的测试用例十分刁钻,必须要考虑到很多的细节问题,在这里给出一组测试用例及运行结果: 95.123 12 548815620517731830194541.899025343415715973535 ...

  5. Struts2实现单文件上传

    首先配置一下web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi ...

  6. 2014年百度之星资格赛第三题Xor Sum

    Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包括了N个正整数,随后 Prometheus 将向 Zeu ...

  7. AC自动机跟随Kuangbing学习笔记

    http://www.cnblogs.com/kuangbin/p/3164106.html kuangbin的博客 第一段代码基本是COPY kuangbin的.. 1.HDU 2222 Keywo ...

  8. yum 安装软件提示错误

    试用yum命令装软件时,遇到了下面的问题,错误提示: rpmdb: unable to join the environment error: db4 error(11) from dbenv-> ...

  9. C# ?? 操作符示例

    static int? GetNullableInt() { return null; } static string GetStringValue() { return null; } static ...

  10. MySQL Update 使用

    备忘: USE `xxx`; ; UPDATE `TB_MB_1` T SET T.`MedicalCount` = ( SELECT S.Total-- ,S.`HospitalID` FROM( ...