现在很多app里面都有侧边栏字母索引列表,看着效果很炫酷,其实不难,那我们现在也来一起自定义一个侧边栏索引列表。
没图说个毛
GIF图:
![](https://img-blog.csdn.net/20171108151514109?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGxfRG9ub3R3ZWFr/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
------------------------------------开始撸代码-------------------------------------
一.首先我们先来写右侧的侧边栏
public class SideBar extends View {
/*绘制的列表导航字母*/
private String words[] = {"↑", "☆", "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 Paint wordsPaint;
/*按下字母背景画笔*/
private Paint bgPaint;
/*每一个item的宽度*/
private int wordWidth;
/*每一个item的高度*/
private int wordHeight;
/*手指按下的字母索引*/
private int touchIndex = -1;
/*手指按下的字母改变接口*/
private onWordsChangeListener listener;
private TextView mTextDialog;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
wordWidth = getMeasuredWidth();
int height = getMeasuredHeight();
wordHeight = height / words.length;
}
开始画字母列表
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < words.length; i++) {
wordsPaint.setTypeface(Typeface.DEFAULT);
wordsPaint.setAntiAlias(true);
wordsPaint.setTextSize(DensityUtils.dp2px(getContext(), 14));
// 是按下的字母则绘制背景
if (touchIndex == i) {
canvas.drawCircle(wordWidth / 2, wordHeight / 2 + i * wordHeight, wordHeight / 2, bgPaint);
wordsPaint.setColor(Color.WHITE);
} else {
wordsPaint.setColor(Color.parseColor("#666666"));
}
//获取文字的宽高
Rect rect = new Rect();
wordsPaint.getTextBounds(words[i], 0, words[i].length(), rect);
//得到文字的X坐标
float wordX = wordWidth / 2 - wordsPaint.measureText(words[i]) / 2;
float wordY = wordHeight / 2 + rect.height() / 2 + wordHeight * i;
canvas.drawText(words[i], wordX, wordY, wordsPaint);
wordsPaint.reset();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN | MotionEvent.ACTION_MOVE:
float y = event.getY();
//关键点===获得我们按下的是那个索引(字母)
int index = (int) (y / wordHeight);
touchIndex = index;
//防止数组越界
if (listener != null && 0 <= touchIndex && touchIndex <= words.length - 1) {
//回调按下的字母
listener.wordsChange(words[touchIndex]);
invalidate();
if (mTextDialog != null) {
mTextDialog.setText(words[index]);
mTextDialog.setVisibility(View.VISIBLE);
}
}
break;
case MotionEvent.ACTION_UP:
touchIndex = -1;
invalidate();
if (mTextDialog != null) {
mTextDialog.setVisibility(View.GONE);
}
break;
}
return true;
}
/*手指按下了哪个字母的回调接口*/
public interface onWordsChangeListener {
void wordsChange(String words);
}
List<Person> mSortList = new ArrayList<Person>();
for (int i = 0; i < date.length; i++) {
Person sortModel = new Person();
sortModel.setName(date[i]);
//汉字转换成拼音
String pinyin = characterParser.getSelling(date[i]);
String sortString = pinyin.substring(0, 1).toUpperCase();
// 正则表达式,判断首字母是否是英文字母
if (sortString.matches("[A-Z]")) {
sortModel.setLetter(sortString.toUpperCase());
} else {
sortModel.setLetter("#");
}
mSortList.add(sortModel);
}
Collections.sort(mSortList, pinyinComparator);
sideBar.setOnWordsChangeListener(new SideBar.onWordsChangeListener() {
@Override
public void wordsChange(String words) {
if ("↑".equals(words)) {
listview.setSelection(0);
} else if ("☆".equals(words)) {
listview.setSelection(1);
} else {
//该字母首次出现的位置
int position = myAdapter.getPositionForSection(words.charAt(0));
if (position != -1) {
listview.setSelection(position+2);
}
}
}
});