功能介绍:这个软件的功能和微信朋友圈的通讯录功能非常相似。就是将后台请求来的数据根据首字母进行分类,然后右侧有索引栏,根据索引栏可以快速的进行搜索。
功能使用场景:通讯录 选择地址(根据地址将数据进行分类) 总之一切使用数据分类的地方都可以使用此功能。在应用开发中属于必不可少的控件。所以透彻的研究它和使用它还是很有必要的。
第一个主要功能 右侧的索引Bar SideBar
public class SideBar extends View {
//私有的OnTouchChangedListener
private OnTouchingLetterChangedListener onTouchingLetterChangedListener;
// 26个首字母
public static String[] b = {"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", "#"};
//开始的选择为-1职位
private int choose = -1;
//我的画笔
private Paint paint = new Paint();
//我的TextView
private TextView mTextDialog;
//当我们滑动的时候会弹出Dialog 这个Dialog主要是一个TextView 这个方法是设置TextView的内容的方法。
public void setTextView(TextView mTextDialog) {
this.mTextDialog = mTextDialog;
}
//SideBar 的构造函数
public SideBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public SideBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SideBar(Context context) {
super(context);
}
/**
*重写OnDraw方法 侧边条实现的核心
*
*每次调用invalidate(); 会调用一次onDraw方法
* */
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int height = getHeight();//得到当前控件的高
int width = getWidth();//得到控件的宽
int singleHeight = height / b.length;//根据总高度除索引的数目得到每个字幕的高度
for (int i = 0; i < b.length; i++) {
paint.setColor(Color.rgb(33, 65, 98));//画笔设置字体颜色
paint.setTypeface(Typeface.DEFAULT_BOLD);//画笔设置默认加粗
paint.setAntiAlias(true);//设置抗锯齿为True
paint.setTextSize(20);//字体号为20
//如果 当前的字幕和
if (i == choose) {
paint.setColor(Color.parseColor("#3399ff"));
paint.setFakeBoldText(true);//对选中的内容进行加粗
}
//算出画每个字幕的位置
float xPos = width / 2 - paint.measureText(b[i]) / 2;
float yPos = singleHeight * i + singleHeight;
canvas.drawText(b[i], xPos, yPos, paint);
paint.reset();//画笔重置 把加粗去掉
}
}
//onTouchEvent之前的拦截dispatchTouchEvent
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
final int action = event.getAction();
final float y = event.getY();
final int oldChoose = choose;
final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;
final int c = (int) (y / getHeight() * b.length);//点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.
switch (action) {
//当手指抬起的时候
case MotionEvent.ACTION_UP:
setBackgroundDrawable(new ColorDrawable(0x00000000));//设置一个完全透明的背景
choose = -1;//无选中项
invalidate();//重画
if (mTextDialog != null) {
//将之前的dialog设置为隐藏
mTextDialog.setVisibility(View.INVISIBLE);
}
break;
default:
setBackgroundResource(R.drawable.sidebar_background);//设置选中时候的背景
if (oldChoose != c) {//新的选择项和旧的不同时
if (c >= 0 && c < b.length) {//选中的项有效
if (listener != null) {//设置回调
listener.onTouchingLetterChanged(b[c]);
}
if (mTextDialog != null) {//对选中的结果进行显示
mTextDialog.setText(b[c]);
mTextDialog.setVisibility(View.VISIBLE);
}
choose = c;//更新新的位置
invalidate();//重画
}
}
break;
}
return true;
}
public void setOnTouchingLetterChangedListener(
OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
}
//定义接口
public interface OnTouchingLetterChangedListener {
public void onTouchingLetterChanged(String s);
}
}
以上这个类是sideBar之后 实现逻辑的核心类,即根据输入的文字进行分析得到首字母序列.
这里追加一个只是点JAVA中的Comparator 泛型接口
这个对象主要是一个比较接口,接入这个接口后要实现
整形方法 public int compare(T o1,T o2)//T是泛型 o1 o2 为比较的两个泛型对象.
你可以在这个方法中定义自己想要的升序或者降序。各种比较逻辑!
而在本文中,使用的比较逻辑如下
public class PinyinComparator implements Comparator< SortModel> {
public int compare( SortModel o1, SortModel o2) {
//当比较对象为# 或 @时进行同类排序。无所谓
if (o1.getSortLetters().equals("@")
|| o2.getSortLetters().equals("#")) {
return -1;
} else if (o1.getSortLetters().equals("#")
|| o2.getSortLetters().equals("@")) {
return 1;
} else {
return
//compareto 会根据字母序列返回ascii的差值如"a".compareTo(b)=-1
//这个方法可以帮助我们进行对字符串的排序工作. o1.getSortLetters().compareTo(o2.getSortLetters());
}
}
}