Android ListView A~Z快速索引(改进版)

来源:互联网 发布:数据库王珊第四版pdf 编辑:程序博客网 时间:2024/06/02 05:27


上一篇文章虽然实现了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传过去就可以了。


改进后的代码如下:

package com.folyd.tuan.view;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Typeface;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;/** * 自定义的View,实现ListView A~Z快速索引效果 *  * @author Folyd *  */public class SlideBar extends View {private Paint paint = new Paint();private OnTouchLetterChangeListenner listenner;// 是否画出背景private boolean showBg = false;// 选中的项private int choose = -1;// 准备好的A~Z的字母数组public static String[] letters = { "#", "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" };// 构造方法public SlideBar(Context context) {super(context);}public SlideBar(Context context, AttributeSet attrs) {super(context, attrs);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 获取宽和高int width = getWidth();int height = getHeight();// 每个字母的高度int singleHeight = height / letters.length;if (showBg) {// 画出背景canvas.drawColor(Color.parseColor("#55000000"));}// 画字母for (int i = 0; i < letters.length; i++) {paint.setColor(Color.BLACK);// 设置字体格式paint.setTypeface(Typeface.DEFAULT_BOLD);paint.setAntiAlias(true);paint.setTextSize(20f);// 如果这一项被选中,则换一种颜色画if (i == choose) {paint.setColor(Color.parseColor("#F88701"));paint.setFakeBoldText(true);}// 要画的字母的x,y坐标float posX = width / 2 - paint.measureText(letters[i]) / 2;float posY = i * singleHeight + singleHeight;// 画出字母canvas.drawText(letters[i], posX, posY, paint);// 重新设置画笔paint.reset();}}/** * 处理SlideBar的状态 */@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {final float y = event.getY();// 算出点击的字母的索引final int index = (int) (y / getHeight() * letters.length);// 保存上次点击的字母的索引到oldChoosefinal int oldChoose = choose;switch (event.getAction()) {case MotionEvent.ACTION_DOWN:showBg = true;if (oldChoose != index && listenner != null && index > 0&& index < letters.length) {choose = index;listenner.onTouchLetterChange(showBg, letters[index]);invalidate();}break;case MotionEvent.ACTION_MOVE:if (oldChoose != index && listenner != null && index > 0&& index < letters.length) {choose = index;listenner.onTouchLetterChange(showBg, letters[index]);invalidate();}break;case MotionEvent.ACTION_UP:showBg = false;choose = -1;if (listenner != null) {if (index <= 0) {listenner.onTouchLetterChange(showBg, "A");} else if (index > 0 && index < letters.length) {listenner.onTouchLetterChange(showBg, letters[index]);} else if (index >= letters.length) {listenner.onTouchLetterChange(showBg, "Z");}}invalidate();break;}return true;}/** * 回调方法,注册监听器 *  * @param listenner */public void setOnTouchLetterChangeListenner(OnTouchLetterChangeListenner listenner) {this.listenner = listenner;}/** * SlideBar 的监听器接口 *  * @author Folyd *  */public interface OnTouchLetterChangeListenner {void onTouchLetterChange(boolean isTouched, String s);}}


Activity中就很容易处理了:

mSlideBar.setOnTouchLetterChangeListenner(new OnTouchLetterChangeListenner() {@Overridepublic void onTouchLetterChange(boolean isTouched, String s) {float_letter.setText(s);if (isTouched) {float_letter.setVisibility(View.VISIBLE);} else {float_letter.postDelayed(new Runnable() {@Overridepublic void run() {float_letter.setVisibility(View.GONE);}}, 100);}int position = array.indexOf(s);mListView.setSelection(position);}});


这样就解决Bug了。哈哈。

原创粉丝点击