先看看效果图
字母选择
1.自定义 View 的基本流程
- 创建 View Class
- 创建 attr 属性文件,确定属性
- View Class 绑定 attr 属性
- onMeasure 测量
- onDraw 绘制
- onTouchEvent ( 用户交互需要处理 )
1.1 创建 View Class
public class LetterSideView extends View {
public LetterSideView(Context context) {
this(context, null);
}
public LetterSideView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public LetterSideView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
1.2 创建 attr
<declare-styleable name="LetterSideView">
<!--默认颜色-->
<attr name="normalColor" format="color"/>
<!--选中颜色-->
<attr name="focusColor" format="color"/>
<!--文字大小-->
<attr name="letterSize" format="dimension"/>
</declare-styleable>
1.3 绑定 attr
private void initAttr(Context context, AttributeSet attrs) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.LetterSideView);
//默认颜色
mNormalColor = array.getColor(R.styleable.LetterSideView_normalColor, mNormalColor);
//选中颜色
mFocusColor = array.getColor(R.styleable.LetterSideView_focusColor, mFocusColor);
//文字大小
mTextSize = array.getDimensionPixelSize(R.styleable.LetterSideView_letterSize, sp2px(mTextSize));
//回收
array.recycle();
}
1.4 onMeasure
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//字母宽度
int letterWidth = getTextWidth("W");
//宽
int width = getPaddingLeft() + getPaddingRight() + letterWidth;
//高
int height = MeasureSpec.getSize(heightMeasureSpec);
//设置宽高
setMeasuredDimension(width, height);
}
1.5 onDraw
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//每个字母的高度
int item = (getHeight() - getPaddingTop() - getPaddingBottom()) / letter.length;
for (int i = 0; i < letter.length; i++) {
//每个字母的中心位置
int letterYCenter = item / 2 + i * item + getPaddingTop();
Paint.FontMetricsInt fontMetricsInt = mNormalPaint.getFontMetricsInt();
int x = getWidth() / 2 - getTextWidth(letter[i]) / 2;
int y = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
int baseLine = letterYCenter + y;
if (letter[i].equals(currentLetter)) {
canvas.drawText(letter[i], x, baseLine, mFocusPaint);
} else {
canvas.drawText(letter[i], x, baseLine, mNormalPaint);
}
}
}
1.6 onTouchEvent
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
letterCallBack.letterCallBack(currentLetter, false);
break;
case MotionEvent.ACTION_MOVE:
//获取当前 Y 位置
float currentY = event.getY();
int item = (getHeight() - getPaddingTop() - getPaddingBottom()) / letter.length;
int currentPosition = (int) currentY / item;
if (currentPosition < 0) {
currentPosition = 0;
}
if (currentPosition > letter.length - 1) {
currentPosition = letter.length - 1;
}
if (letter[currentPosition].equals(currentLetter)) {
return true;
}
currentLetter = letter[currentPosition];
if (letterCallBack != null) {
letterCallBack.letterCallBack(currentLetter, true);
}
invalidate();
break;
}
return true;
}