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

你可能感兴趣的:(android)