效果图:
字母索引
public AlphabeticalIndexView(Context context) {
this(context, null);
}
public AlphabeticalIndexView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public AlphabeticalIndexView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int w = (int) (getPaddingLeft() + getPaddingRight() + DisplayUtil.getTextWidth("W", mPaint));
int h = getMeasuredHeight();
setMeasuredDimension(w, h);
}
private void init(Context context) {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setTextSize(DisplayUtil.sp2px(context, 15));
}
因为不是viewGroup
,所以不必重写onLayout
函数,我们直接进入onDraw
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 每个字母所占用的高度
for (int i = 0; i < mLetters.length; i++) {
String letter = mLetters[i];
if (letter.equals(mCurrentTouchLetter))
mPaint.setColor(Color.BLUE);
else
mPaint.setColor(Color.GRAY);
// 获取字体的宽度
float measureTextWidth = mPaint.measureText(letter);
// 获取内容的宽度
int contentWidth = getWidth() - getPaddingLeft() - getPaddingRight();
canvas.drawText(letter, getPaddingLeft() + (contentWidth - measureTextWidth) / 2, getPaddingTop() + mSingLetterHeight * i + DisplayUtil.getTextBaseLine(mPaint), mPaint);
}
}
这里可能有点疑惑,为什么要用内容的宽度减去字体的宽度然后除于2
,这是因为每个字母的宽度都不一样,如果不这样做的画,那么比如I
就会和A W
等字母左对齐,我们这样做的目的就是为了都居中。
这样我们就实现了一个静态的页面没我们要让他触摸改变,我们就重写onTouchEvent
进行操作,并且添加相应的回调。
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
// 获取当前手指触摸的Y位置
float fingerY = ev.getY();
int pos = (int) (fingerY / mSingLetterHeight);
if (pos > -1 && pos < mLetters.length && !mLetters[pos].equals(mCurrentTouchLetter)) {
mCurrentTouchLetter = mLetters[pos];
triggerTouchListener(true);
invalidate();
}
break;
case MotionEvent.ACTION_UP:
triggerTouchListener(false);
break;
}
return true;
}
private void triggerTouchListener(boolean isTouch) {
if (mTouchListener != null)
mTouchListener.onTouch(mCurrentTouchLetter, isTouch);
}
// 设置触摸监听
private SideBarTouchListener mTouchListener;
public void setOnSideBarTouchListener(SideBarTouchListener touchListener) {
this.mTouchListener = touchListener;
}
public interface SideBarTouchListener {
void onTouch(String letter, boolean isTouch);
}