zoukankan      html  css  js  c++  java
  • Android ListView A~Z快速索引(改进版)


    上一篇文章虽然实现了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);
    	}
    
    	@Override
    	protected 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的状态
    	 */
    	@Override
    	public boolean dispatchTouchEvent(MotionEvent event) {
    		final float y = event.getY();
    		// 算出点击的字母的索引
    		final int index = (int) (y / getHeight() * letters.length);
    		// 保存上次点击的字母的索引到oldChoose
    		final 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() {
    
    					@Override
    					public void onTouchLetterChange(boolean isTouched, String s) {
    
    						float_letter.setText(s);
    						if (isTouched) {
    							float_letter.setVisibility(View.VISIBLE);
    						} else {
    							float_letter.postDelayed(new Runnable() {
    
    								@Override
    								public void run() {
    									float_letter.setVisibility(View.GONE);
    								}
    							}, 100);
    						}
    						int position = array.indexOf(s);
    						mListView.setSelection(position);
    					}
    				});
    



    这样就解决Bug了。哈哈。

  • 相关阅读:
    JVM源码分析 规格严格
    Smack 规格严格
    Java动态编译 规格严格
    RPM仓库地址 规格严格
    使用控制台程序测试DLL依赖
    TestNG 使用入门
    白羊座二:星星的一周
    路遇两骗子
    《落地,请开手机》里面最经典的一句台词
    今天明白的一个道理
  • 原文地址:https://www.cnblogs.com/james1207/p/3283658.html
Copyright © 2011-2022 走看看