完美的垂直刻度尺

闲来没事,做个小东西玩玩~

网上的例子有一些,不过一天不装逼,我就难受,所以决定自己搞!这个垂直刻度尺可以滑动,可以配合硬件根据结果展示在刻度尺上,话不多少,先看效果吧~



是不是还可以?

上代码:

public class HeightTestRule extends View {
    private static final int Max = 225;//中间显示刻度不超过225cm,比姚明高的不接受,哈哈
    private static final int Limit_Y = 240;

    protected Scroller mScroller;//靠它控制滑动
    protected float mDownMotionY;
    protected float mLastMotionY;
    protected float mTotalMotionY;

    protected static final int INVALID_POINTER = -1;
    protected int mActivePointerId = INVALID_POINTER;

    int indicateHeight;//刻度的高度 一般1dp即可
    int indicateGap;//刻度之间的间距
    int verticalLineWidth;
    Paint mPaint = new Paint();
    private Bitmap longBitmap, shortBitmap;//长刻度,短刻度
    private RuleChangeListener ruleChangeListener;//scrollY改变会触发

    public HeightTestRule(Context context, AttributeSet attrs) {
        super(context, attrs);
        //流畅度提升,开启硬件加速
        setLayerType(View.LAYER_TYPE_HARDWARE, mPaint);
        init();
    }

    public interface RuleChangeListener {
        void onChange(int level);
    }

    public void setRuleChangeListener(RuleChangeListener ruleChangeListener) {
        this.ruleChangeListener = ruleChangeListener;
    }

    //滚动到指定刻度
    public void scroll(int height) {
        if (height <= Max) {
            if (!isMoving()) {
                int finalY = Max * (indicateHeight + indicateGap) - indicateHeight;
                int deltaY = finalY - getScrollY() - height * (indicateGap + indicateHeight);
                mScroller.startScroll(0, getScrollY(), 0, deltaY, 500);
                invalidate();
            }
        } else {
            Toast.makeText(getContext(), "身高不能大于" + Max + "cm", Toast.LENGTH_SHORT).show();
        }
    }

    //是否在滚动,在滚动就不处理,否则滚动到指定位置
    public boolean isMoving() {
        return mScroller.computeScrollOffset();
    }

    //回到原点
    public void reset() {
        int finalY = Max * (indicateHeight + indicateGap) - indicateHeight;
        mScroller.startScroll(0, getScrollY(), 0, finalY - getScrollY(), 500);
        invalidate();
    }

    void init() {
        indicateGap = getResources().getDimensionPixelSize(R.dimen.indicate_gap);
        indicateHeight = getResources().getDimensionPixelSize(R.dimen.indicate_height);
        verticalLineWidth = getResources().getDimensionPixelSize(R.dimen.vertical_line_width);
        mScroller = new Scroller(getContext(), new ScrollInterpolator());

        mPaint.setStrokeWidth(verticalLineWidth);
        mPaint.setColor(getResources().getColor(R.color.indicateColor));
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        longBitmap = createLongLine();
        shortBitmap = createshortLine();
        //开始滚动到原点
        int finalY = Max * (indicateHeight + indicateGap) - indicateHeight;
        scrollTo(0, finalY);
    }

    private static class ScrollInterpolator implements Interpolator {
        public ScrollInterpolator() {
        }

        public float getInterpolation(float t) {
            t -= 1.0f;
            return t * t * t * t * t + 1;
        }

    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            // Don't bother scrolling if the page does not need to be moved
            if (getScrollX() != mScroller.getCurrX() || getScrollY() != mScroller.getCurrY()) {
                scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            }
            invalidate();
        }
    }

    private Bitmap createLongLine() {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.line_long, null);
        view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();
        return bitmap;
    }

    //根据布局直接生成bitmap,就是这么懒
    private Bitmap createshortLine() {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.line_short, null);
        view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();
        return bitmap;
    }

    private Bitmap createLabel(int scrollY) {
        TextView view = (TextView) LayoutInflater.from(getContext()).inflate(R.layout.indicate_label, null);
        int count = (int) (scrollY / indicateHeight);
        view.setText(String.valueOf(count));
        view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();
        return bitmap;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int height = Limit_Y * (indicateGap + indicateHeight);
        //画竖线
        canvas.save();
        canvas.translate(getScrollX(), getScrollY());
        canvas.drawLine(0, 0, 0, height, mPaint);
        canvas.restore();
        int count = height / indicateGap;
        //画刻度
        for (int i = count - 1; i >= 0; i--) {
            canvas.save();
            canvas.translate(getScrollX(), 0);
            canvas.translate(0, (Limit_Y - i) * indicateHeight + (Limit_Y - i - 1) * indicateGap);
            if (i % 10 == 0) {
                canvas.drawBitmap(longBitmap, 0, 0, mPaint);
                //画label
                Bitmap label = createLabel(i * indicateHeight);
                canvas.save();
                canvas.translate(longBitmap.getWidth() * 2, -(label.getHeight() - indicateHeight) / 2);
                canvas.drawBitmap(label, 0, 0, mPaint);
                canvas.restore();
            } else {
                canvas.drawBitmap(shortBitmap, 0, 0, mPaint);
            }
            canvas.restore();
        }

    }

    @Override
    public void scrollTo(int x, int y) {
        //最多不超过
        if (y >= 0 && y + getHeight() <= (indicateGap + indicateHeight) * 254) {
            super.scrollTo(x, y);
        }
        if (ruleChangeListener != null) {
            int scrollY = getScrollY();
            int finalY = Max * (indicateHeight + indicateGap) - indicateHeight;
            int level = (finalY - scrollY) / (indicateHeight + indicateGap);
            ruleChangeListener.onChange(level);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }
                mDownMotionY = mLastMotionY = ev.getY();
                mTotalMotionY = 0;
                mActivePointerId = ev.getPointerId(0);
                break;
            case MotionEvent.ACTION_MOVE:
                final int pointerIndex = ev.findPointerIndex(mActivePointerId);
                final float y = ev.getY(pointerIndex);
                final float deltaY = mLastMotionY - y;

                mTotalMotionY += Math.abs(deltaY);

                if (Math.abs(deltaY) >= 1.0f) {
                    scrollBy(0, (int) deltaY);
                    mLastMotionY = y;
                } else {
                    awakenScrollBars();
                }

                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                //Do nothing
                break;
        }
        return true;
    }


}

理解起来很简单,我就不再解释了,有问题的可以留言,源码下载地址:

http://download.csdn.net/detail/rocketlong/9685539


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值