6.自定义view-侧边字母导航LetterNavigationBar

1.效果

2.实现原理

1.绘制右侧的字母

2.onTouchEvent 中获取点击、滑动的位置,在通过invalidate() 去重新绘制,

​ 回调给activity去处理中间显示的文字

核心代码:

    @Override
    protected void onDraw(Canvas canvas) {
        mItemHeight = (getHeight() - getPaddingTop() - getPaddingBottom()) / mLetters.length;
        for (int i = 0; i < mLetters.length; i++) {
            int x = (int) (getWidth() / 2 - mPaint.measureText(mLetters[i]) / 2);
            int middleHeight = mItemHeight * i + getHeight() / mLetters.length / 2 + getPaddingTop();

            Paint.FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
            int dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;

            int baseLine = middleHeight + dy;
            //当前滑动到的字母 高亮显示
            if (mCurrentLetter.equals(mLetters[i])) {
                canvas.drawText(mLetters[i], x, baseLine, mHighPaint);
            } else {
                canvas.drawText(mLetters[i], x, baseLine, mPaint);
            }

        }
    }
 @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                //获取当前触摸的下标
                int currentIndex = getCurrentIndex(event.getY());

                //防止重绘
                if (!mCurrentLetter.equals(mLetters[currentIndex])) {
                    mCurrentLetter = mLetters[currentIndex];
                    if (mLetterTouchListener != null) {
                        mLetterTouchListener.onTouch(mCurrentLetter, true);
                    }
                    invalidate();

                }
                break;
            case MotionEvent.ACTION_UP:
                if (mLetterTouchListener != null) {
                    mLetterTouchListener.onTouch(mCurrentLetter, false);
                }
                break;
        }

        return true;
    }

源码地址

posted @ 2020-11-11 15:16  Nixon  阅读(129)  评论(0编辑  收藏  举报