Android侧栏A-Z的快速滑动搜索想必大家并不陌生,很多应用里面都有这样的功能出现。最常见的如电话联系人列表、好友列表、城市列表等等。快速搜索就是方便我们快速定位到我们要找的信息。比如我们想找姓氏为刘的,那么我们只需要点击一下L就能搜索到好友里面的姓氏拼音首字母以L开头的,当然姓氏刘也就搜出来的,有可能以L开头的姓氏比较多,比如李、郎、鲁、柳、雷、刘、林、蓝、吕等,而我们想找到刘这个姓我们可以让含有L的这些姓氏全都显示出来供我们来选择。
要想实现这些快速搜索首先我们要用侧边要有A-Z的选项供我们选择。
那么我们就先来说一说侧边栏#和A-Z的实现。实现这个功能其实也很简单,我们需要自己自定义一个控件,点击查看自定义控件。自定义控件离不了onDraw。我们这次自定义控件不需要onMeasure和onLayout这两个。但是我们需要实onSizeChanged,它是在布局发生变化时的回调函数,由于我们的侧栏是滑动搜索onTouchEvent也是离不了的。
那么我们来实现一下侧栏的功能吧。先来一个最简单的也是必不可少的决定侧边栏要显示的内容的一步
private String[] mSideLetter = { "#","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",};
我们要显示的这些内容既然已经确定了,那么我们就要为这些内容分配相应的高度和宽度。每个字母的高度是有屏幕的高度来决定的。我们根据获取到的屏幕的高度/字母的数量 = 每个字母显示的高度。宽度怎么办呢?因为我们的这些内容是不可能自己去每一个字母一换行的,而我们又想要的是每个字母是一行。我们可以根据字母的数量来决定显示的行数,那么我们就可以根据行数来决定每行要显示的字母是什么。比如#在第一行那么当i为0 的时候我们就可以设置这行显示的为#
private int getTextHeight(String text) {
//获取文本的高度
Rect bounds = new Rect();
paint.getTextBounds(text,0,text.length(), bounds);
return bounds.height();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < mSideLetter .length; i++) {
float x = letterWidth/2;
float y = letterHeight/2 + getTextHeight(mSideLetter [i])/2 + i*letterHeight;
paint.setColor(lastIndex==i?Color.BLACK:Color.WHITE);
canvas.drawText(mSideLetter [i], x, y, paint);
}
}
至于为什么float x = letterWidth/2。首先要清楚drawText不是以文字的左上角开始绘制,而是以baseLine为基线绘制。如果我们要想让字母居中,那么我们就需要X的坐标点在字母的中间位置,也就是字母宽度的一半了。高度float y = letterHeight/2 + getTextHeight(mSideLetter [i])/2 + i*letterHeight; letterHeight/2 + getTextHeight(mSideLetter [i])/2所起的作用就是文字居中显示, i*letterHeight则是显示的高度。怎么理解呢?比如说X的显示位置,X的高度已经获取到了,那么X的显示位置高度就是在前面所有的字母的高度之上再加上自己的高度就是显示的位置y了。
package lyx.robert.quicksearch.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Paint.Align;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import lyx.robert.quicksearch.utils.DisplayUtil;
public class SideLetterBar extends View{
private String[] mSideLetter = { "#","A", "B", "C",