您的位置:首页 > 移动开发 > Android开发

Android 自定义View——联系人右侧字母索引

2017-11-08 14:39 441 查看

现在很多app里面都有侧边栏字母索引列表,看着效果很炫酷,其实不难,那我们现在也来一起自定义一个侧边栏索引列表。

没图说个毛

GIF图:


------------------------------------开始撸代码-------------------------------------一.首先我们先来写右侧的侧边栏 
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;


获取到控件的宽高,计算出每个item的宽高
@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);
}


三.listview列表:将汉字转为拼音排序
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);
}
}
}
});


好啦! 大工告成,是不是很简单呢?嘿嘿。。。

==============源码下载============
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: