import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.widget.TextView;
/**
* 字母索引表
*/
public class LetterView extends View {
private static final String[] ARRAY_LETTER = new String[]{
"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 static final String LETTER_TEXT_COLOR = "#55000000";
/**
* 背景颜色
*/
private static final String LETTER_BACKGROUND_NORMAL = "#00000000";
/**
* 背景触摸时的颜色
*/
private static final String LETTER_BACKGROUND_PRESSED = "#11000000";
private Paint mLetterPaint;
/**
* 用于记录临时位置
*/
private int mTmpPos = -1;
/**
* 当前显示位置
*/
private int mCurrentPos = -1;
/**
* 字母提示文本
*/
private TextView mTvHint;
private int mHeight;
private int mWidth;
/**
* 显示提示字母
*
* @param mTv 要显示的控件
*/
public void setHintLetterText(TextView mTv) {
this.mTvHint = mTv;
}
public interface OnLetterChangeListener {
/**
* 监听回调
*
* @param currentLetter 当前的字母 如: A
*/
void onLetterChange(String currentLetter);
}
private OnLetterChangeListener olcl;
/**
* 用于监听当前的字母
*
* @param l OnCurrentLetterListener类型
*/
public void setOnLetterChangeListener(OnLetterChangeListener l) {
//防止重复注册
if (this.olcl == null) {
this.olcl = l;
} else {
// 直接抛出异常
throw new RuntimeException("LetterView不允许重复注册OnLetterChangeListener");
}
}
public LetterView(Context context) {
this(context, null);
}
public LetterView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LetterView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
/**
* 初始化Paint
*/
private void initPaint() {
mLetterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLetterPaint.setTextSize((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
14, getResources().getDisplayMetrics()));
mLetterPaint.setTextAlign(Paint.Align.CENTER);
mLetterPaint.setColor(Color.parseColor(LETTER_TEXT_COLOR));
}
@Override
protected void onDraw(Canvas canvas) {
int letterHeight = mHeight / ARRAY_LETTER.length;
for (int i = 0; i < ARRAY_LETTER.length; i++) {
String letter = ARRAY_LETTER[i];
canvas.drawText(letter, mWidth / 2, (i + 1) * letterHeight, mLetterPaint);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mHeight = getMeasuredHeight();
mWidth = getMeasuredWidth();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
getCurrentPostion(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
actionDownTouch();
break;
case MotionEvent.ACTION_MOVE:
actionMoveTouch();
break;
case MotionEvent.ACTION_UP:
actionUpTouch();
break;
}
invalidate();
return true;
}
/**
* 获取当前位置
*
* @param event
*/
private void getCurrentPostion(MotionEvent event) {
float y = event.getY();
int letterHeight = mHeight / ARRAY_LETTER.length;
mCurrentPos = (int) (y / letterHeight);
if (mCurrentPos > (ARRAY_LETTER.length - 1)) {
mCurrentPos = ARRAY_LETTER.length - 1;
} else if (mCurrentPos < 0) {
mCurrentPos = 0;
}
}
private void actionDownTouch() {
mTmpPos = mCurrentPos;
setBackgroundColor(Color.parseColor(LETTER_BACKGROUND_PRESSED));
if (mTvHint != null) {
mTvHint.setVisibility(VISIBLE);
mTvHint.setText(ARRAY_LETTER[mCurrentPos]);
}
if (olcl != null) {
olcl.onLetterChange(ARRAY_LETTER[mCurrentPos]);
}
}
private void actionMoveTouch() {
// 通过比较位置是否发生改变决定是否调用
if (mTvHint != null && (mTmpPos != mCurrentPos)) {
mTvHint.setText(ARRAY_LETTER[mCurrentPos]);
}
if (olcl != null && (mTmpPos != mCurrentPos)) {
olcl.onLetterChange(ARRAY_LETTER[mCurrentPos]);
mTmpPos = mCurrentPos;
}
}
private void actionUpTouch() {
mTmpPos = -1; // 重置临时位置
// 手指放开时调用
setBackgroundColor(Color.parseColor(LETTER_BACKGROUND_NORMAL));
if (mTvHint != null) {
// 加入文本消失时的动画
AlphaAnimation alphaAnimation = new AlphaAnimation(1f, 0f);
alphaAnimation.setDuration(300);
mTvHint.setAnimation(alphaAnimation);
mTvHint.setVisibility(GONE);
}
}
}
字母索引表
最新推荐文章于 2023-09-07 13:30:42 发布