自定义View - 12.字母索引列表

2018-07-01  本文已影响12人  zsj1225

要完成的效果:


Gif_20180701_142124.gif

1 自定义属性

2 onMeasure

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //2 onMeasure
        //宽度,左右padding + 文字宽度
        //3.绘制中间文本
        String text = "A";
        //字体的宽度高度
        if (mBounds == null) {
            mBounds = new Rect();
        }
        mDefaultPaint.getTextBounds(text, 0, text.length(), mBounds);

        int width = mBounds.width() + getPaddingLeft() + getPaddingRight();

        //获取屏幕高度
        WindowManager wm = (WindowManager) getContext()
                .getSystemService(Context.WINDOW_SERVICE);
        int height = wm.getDefaultDisplay().getHeight();

        int widthSize = resolveSize(width, widthMeasureSpec);
        int heightSize = resolveSize(height, heightMeasureSpec);

        setMeasuredDimension(widthSize, heightSize);
    }

3 绘制

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //3 绘制
        //每个文字的高度空间
        int letterSpace = getMeasuredHeight() / LetterFilterListView.mLetters.length;
        for (int i = 0; i < LetterFilterListView.mLetters.length; i++) {
            //文字中间的位置
            // 0 --> 0 + letterSpace /2
            // 1 --> letterSpace + letterSpace /2
            int latterCenter = letterSpace * i + letterSpace / 2;
            //指定中间位置,绘制文本
            Paint.FontMetricsInt fontMetricsInt = mDefaultPaint.getFontMetricsInt();
            if (mBounds == null) {
                mBounds = new Rect();
            }
            mDefaultPaint.getTextBounds(mLetters[i], 0, mLetters[i].length(), mBounds);
            int x = getMeasuredWidth() / 2 - mBounds.width() / 2;

            int baseLine = latterCenter + (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;

            if (mLetters[i].equals(mTouchLetter)) {
                canvas.drawText(LetterFilterListView.mLetters[i], x, baseLine, mTouchPaint);
            } else {
                canvas.drawText(LetterFilterListView.mLetters[i], x, baseLine, mDefaultPaint);
            }
        }
    }

4 onTouchEvent

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //4 onTouch
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                //4.1 获取当前的位置
                float y = event.getY();
                //4.2 获取y对应的字母
                // 每个文字的高度空间
                int letterSpace = getMeasuredHeight() / LetterFilterListView.mLetters.length;
                // A = 0  <==> y / letterSpace =0
                int number = (int) (y / letterSpace);

                //4.4 范围为题
                if (number < 0) {
                    number = 0;
                }

                if (number > mLetters.length - 1) {
                    number = mLetters.length - 1;
                }
                String touchLetter = mLetters[number];
                //4.5 优化,减少invalidate的调用
                if (touchLetter.equals(mTouchLetter)) {
                    return true;
                }

                if (mOnTouchLetterListener != null) {
                    mOnTouchLetterListener.OnTouchLetter(touchLetter);
                }
                mTouchLetter = touchLetter;
                invalidate();
                break;

            case MotionEvent.ACTION_UP:
                //4.3 松手 恢复到原来的状态
                mTouchLetter = "";
                if (mOnTouchLetterListener != null) {
                    mOnTouchLetterListener.OnTouchLetter(mTouchLetter);
                }
                invalidate();
                break;
            default:
                break;
        }
        return true;
    }

5 回调

    //5 回调
    interface OnTouchLetterListener {
        void OnTouchLetter(String touchLetter);
    }

    public void setOnTouchLetterListener(OnTouchLetterListener onTouchLetterListener) {
        mOnTouchLetterListener = onTouchLetterListener;
    }

完整代码:letterfilterlistview

上一篇下一篇

猜你喜欢

热点阅读