这几天无意间翻到之前写的一篇关于自定义通讯录导航栏的博客,文章中只是做了一点点简单介绍,写的并不完整。由于这段时间比较空闲,索性把整篇文章重新整理一遍。
这样的一个控件实现起来不难,需要对自定义view有一定的基础,也要了解怎么实现一个集合的排序。大体思路很简单。
- 首先完成view的基本绘制以及相关的内部逻辑。
- 其次,就是要对联系人数据进行排序,即姓名首字母按26个英文字母进行排序,说到排序不得不说的两个接口Comparable和Comparator。利用这两个接口中的一个,我们可以很方便的实现集合排序的功能。
- 接下来就可以使用ListView来展示联系人数据了,关于ListView的使用相信大家都已经十分的熟练了,也就不多说了。
- 最后要实现点击导航栏字母使ListView滚动到相应的位置,编写一个相关回调接口即可。
原理还是比较简单的,有了思路,做事情就会事半功倍。接下来,首先考虑自定义导航栏的实现,其实就是需要绘制一个#号和26个英文字母竖直排列的View。接下来看这样的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;
import android.widget.TextView;
import cn.manchester.app.contactsnav.R;
/**
* 右侧导航栏字母列表
*
* @author Administrator
*/
public class SideBar extends View {
/*
* 默认的导航栏中字母的大小
*/
private static final int DEFAULT_ALPHA_SIZE = 18;
/*
* 字母导航栏选择时,在中部显示所选择字母的TextView
*/
private TextView mDialog;
/*
* 字母导航栏选择事件回调接口
*/
private OnLetterSelectedListener mOnLetterSelectedListener;
/*
* 字母列表内容
*/
private static final String[] ALPHA_LIST = {
"#", "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 mChoiceIndex;
/*
* 画笔
*/
private Paint mPaint;
/*
* 默认字母颜色
*/
private static final int DEFAULT_CHARACTER = Color.rgb(33, 66, 99);
/*
* 选中字母颜色
*/
private static final int CHIOCED_CHARACTER = Color.parseColor("#FF0000");
public SideBar(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
mPaint.setAntiAlias(true); // 抗锯齿,字体圆滑
mPaint.setColor(DEFAULT_CHARACTER); // 设置字体颜色
mPaint.setTypeface(Typeface.DEFAULT_BOLD); // 设置字体为粗体
mPaint.setTextSize(sp2px(DEFAULT_ALPHA_SIZE));
}
/**
* 字母导航栏选中事件回调接口
*
* @author Administrator
*/
public interface OnLetterSelectedListener {
/**
* 字母被选中事件回调方法
*
* @param letter 被选中的字母
*/
void onLetterSelected(String letter);
}
/**
* 设置字母导航栏字母被选中时的回调接口
*
* @param listener 接口
*/
public void setOnLetterSelectedListener(OnLetterSelectedListener listener) {
mOnLetterSelectedListener = listener;
}
public int sp2px(float spValue) {
final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 获取整个SideBar的宽和高
int width = getWidth();
int height = getHeight();
// 平均每行所分配到的高度值
int singleHeight = height / ALPHA_LIST.length;