字母索引表

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);
        }
    }

}

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值