Android 自定义View-字母索引表

厌伴老儒烹瓠叶,强随举子踏槐花。这篇文章主要讲述Android 自定义View-字母索引表相关的知识,希望能为你提供帮助。
在有些android应用中,为了方便快速定位,经常会看到屏幕右侧有一个字母索引表,今天尝试使用自定义View的方式实现了索引表的基本布局。
字母索引表的样式如下面的示意图所示,
【Android 自定义View-字母索引表】

Android 自定义View-字母索引表

文章图片

此时我们至少需要知道以下几个参数值:1.字母大小; 2.单个字母所在区域的宽度; 3.单个字母所在区域的高度。现在看如何实现:
/**
* 26个英文字母以及一个#字符,#字符是为了索引非英文字母的内容,比如电话号码。
*/
private String[] mAlphabetTable = { "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", "#" }; /** * 单个字母的大小 */ private int mAlphabetSize = 0; /** * 字母表的宽度 */ private int mWidth = 0; /** * 字母表的高度 */ private int mHeight = 0; /** * 窗口高度 */ private int mDisplayHeight; /** * 单个字母所在区域的高度 */ private int mStepPixel; private int mFastScrollViewHeight = 0; private Rect[] mAlphabetRect = new Rect[27]; private Rect mPointRectAll = new Rect(); private static int mAlphabetLeftPadding = 0; private boolean[] mPoint = new boolean[27]; public AlphabetFastScorll(Context context) { this(context, null); }public AlphabetFastScorll(Context context, AttributeSet attrs) { super(context, attrs); this.setAlpha(1.0f); //设置透明度1 DisplayMetrics metric = new DisplayMetrics(); ((WindowManager) getContext().getSystemService(getContext().WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metric); mDisplayHeight = metric.heightPixels; //获取窗口高度 }

 
在构造函数里,只设置了索引表的透明度和初始化mDisplayHeight参数。索引表的绘制工作大部分是在onDraw()里完成。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); }@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mStepPixel = getContext().getResources().getDimensionPixelOffset(R.dimen.fast_scroll_size); mFastScrollViewHeight = mStepPixel * 27;
//初始化27个字母每个字母对应所在区域的大小范围 InitAlphabetRect();

//初始化字母索引表的背景大小 initPointRect(mFastScrollViewHeight, mStepPixel); //设置背景颜色 Paint paintB = new Paint(); paintB.setColor(ContextCompat.getColor(getContext(), R.color.colorAccent)); //paintB.setAlpha(0); canvas.drawRect(mPointRectAll, paintB);
//设置字母中大小,颜色,位置等 Paint paint = new Paint(); float textSize = getContext().getResources().getDimensionPixelOffset(R.dimen.asus_index_size); paint.setColor(ContextCompat.getColor(getContext(), R.color.fast_scroll_text_color)); paint.setTextAlign(Align.CENTER); paint.setTextSize(textSize); paint.setAntiAlias(true); for (int i = 0; i < mAlphabetRect.length; i++) { int x = (mAlphabetRect[i].left + mAlphabetRect[i].right) / 2; int y = mAlphabetRect[i].bottom; y = y - (int) (0.5 * (mStepPixel - textSize));
//字母绘制在mAlphabetRect[i]区域中间 canvas.drawText(mAlphabetTable[i], x, y, paint); } }private void InitAlphabetRect() { for (int i = 0; i < mAlphabetRect.length; i++) { mAlphabetRect[i] = new Rect(); mAlphabetRect[i].left = mAlphabetLeftPadding; mAlphabetRect[i].right = mAlphabetLeftPadding + this.getWidth(); //Log.d(TAG,"InitAlphabetRect right = " + mAlphabetRect[i].right); if (i == 0) { mAlphabetRect[i].top = 0; mAlphabetRect[i].bottom = mStepPixel; } else { mAlphabetRect[i].top = mAlphabetRect[i-1].top + mStepPixel; mAlphabetRect[i].bottom = mAlphabetRect[i].top + mStepPixel; } } }private void initPointRect(int fastScrollViewHeight, int stepPixel) { int canvasWidth = getContext().getResources().getDimensionPixelOffset(R.dimen.asus_index_canvas_width); mPointRectAll = new Rect(); mPointRectAll.left = 0; mPointRectAll.right = canvasWidth; mPointRectAll.top = 0; mPointRectAll.bottom = this.getHeight(); }

  在onDraw()里做了以下几件事情:
1,初始化索引表字母所在区域的范围:新建一个Rect对象,设置其左右和上下大小。宽度大小由布局文件中提供,高度为mStepPixel。
2,初始化索引表背景范围:宽 = asus_index_canvas_width,高 = this.getHeight();
3,已经知道每个字母所在区域范围以及索引背景范围,新建两个Paint在Canves上进行绘制;
 
通过以上几步就可以简单实现索引表控件,光光显示一个索引表肯定没啥意义。一般都是将索引表与ListView组合,实现快速定位功能。下篇准备模仿联系人应用,实现通过索引表快速定位到联系人。

    推荐阅读