1. 程式人生 > >Android-仿千度尺的橫向滾動選擇器

Android-仿千度尺的橫向滾動選擇器

先上一個效果圖

主要核心方法,這裡有一個問題ontouchEvent如果返回super,則move事件不會繼續執行,down事件則沒問題.所以這裡要返回true

其次,就是計算滾動距離的問題

@Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                float scrollX = event.getX();
                mOffset = scrollX - downX;
                // 向右滑動
                if (scrollX > downX) {
                    // 如果滑動距離大於一個條目的大小,則減1
                    if (scrollX - downX >= mItemSize) {
                        if (selectNum > 0) {
                            mOffset = 0;
                            selectNum = selectNum - 1;
                            downX = scrollX;
                            if (mOnRollingListener != null) {
                                mOnRollingListener.onRolling(selectNum, data.get(selectNum));
                            }
                        }
                    }
                } else {
                    //向左滑動大於一個條目的大小,則加1
                    if (downX - scrollX >= mItemSize) {
                        if (selectNum < data.size() - 1) {
                            mOffset = 0;
                            selectNum = selectNum + 1;
                            downX = scrollX;
                            if (mOnRollingListener != null) {
                                mOnRollingListener.onRolling(selectNum, data.get(selectNum));
                            }
                        }
                    }
                }
                invalidate();
                break;

            case MotionEvent.ACTION_UP:
                //擡起手指時,偏移量歸零,相當於回彈。
                mOffset = 0;
                invalidate();
                break;
            default:
                break;
        }
        return true;
    }

下一步則是繪製流程

注: 這步有一個問題就是如果文字過長,會導致遮住其他文字,所以我這取itemsize的時候,需要取最大值來得到能夠獲取的itemsize.並且修正可以看到的大小

   @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 獲取寬度
        int width  = getWidth();
        int height = getHeight();
        // 獲取每個條目的大小
        if (seeSize == 0) {
            return;
        }
        mItemSize = width / seeSize;
        int tmp = 0;
        for (String datum : data) {
            mOthers.getTextBounds(datum, 0, datum.length(), mRect);
            int textWidth = mRect.width();
            if (textWidth > tmp) {
                tmp = textWidth;
            }
        }
        // 修正文字過大導致長度bug
        mItemSize = Math.max(mItemSize, tmp);
        seeSize = width / mItemSize;
        // | dfadf |  dsafa | afasdf |
        // 得到選中的條目
        // 畫出第一個
        for (int j = 0; j < data.size(); j++) {
            String datum = data.get(j);
            mOthers.getTextBounds(datum, 0, datum.length(), mRect);
            int textWidth  = mRect.width();
            int textHeight = mRect.height();
            if (j != selectNum) {
                // 畫其他的
                if (j < selectNum) {
                    int a = selectNum - j;
                    canvas.drawText(datum, mItemSize * seeSize / 2 - textWidth / 2 - a * mItemSize + mOffset, height / 2 - textHeight / 2, mOthers);
                } else {
                    int a = j - selectNum;
                    canvas.drawText(datum, mItemSize * seeSize / 2 - textWidth / 2 + a * mItemSize + mOffset, height / 2 - textHeight / 2, mOthers);
                }
            } else {
                canvas.drawText(datum, mItemSize * seeSize / 2 - textWidth / 2 + mOffset, height / 2 - textHeight / 2, mSelect);
            }
        }
    }

更多詳細可以移步我的github

EHorizontalSelectedView