自定义View安卓学习

自定义View - 5.仿QQ运动步数进度效果

2018-06-10  本文已影响16人  zsj1225
f1nk2-5payz.gif

今天我们来做一个这个效果.

1.自定义属性

这里就不写了.后面会附上GitHub地址.
不懂自定义属性,可以看:https://www.jianshu.com/p/07ee1fcd64b3

2.onMeasure (指定控件的宽高)

    //指定控件的宽高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //获取测量模式
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        //确定大小,给多少用多少
        int width = MeasureSpec.getSize(widthMeasureSpec);
        //不确定大小,wrap_content .给一个默认值.
        int defaultSize = dip2px(getContext(), 200);
        if (widthMode == MeasureSpec.AT_MOST) {
            width = defaultSize;
        }
        width = width + getPaddingLeft() + getPaddingRight();
        //高
        int height = MeasureSpec.getSize(heightMeasureSpec);
        //不确定大小,wrap_content .给一个默认值.
        if (heightMode == MeasureSpec.AT_MOST) {
            height = defaultSize;
        }
        height = height + getPaddingTop() + getPaddingBottom();
        //指定控件的宽高,要正方形.取宽高比较后的最小值
        setMeasuredDimension(Math.min(width, height), Math.min(width, height));
    }

3.onDraw (绘制)

3.1 绘制外圆弧

QQ步行进度外圆弧分析
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画外圆弧
        if (mRectF == null) {
            mRectF = new RectF(mProgressWidth / 2 + getPaddingLeft(), mProgressWidth / 2 + getPaddingTop(),
                    getWidth() - mProgressWidth / 2 - getPaddingRight(),
                    getHeight() - mProgressWidth / 2 - getPaddingBottom());
        }
        canvas.drawArc(mRectF, 135, 270, false, mOutPaint);
    }

3.2 绘制内圆弧

    @Override
    protected void onDraw(Canvas canvas) {
         float percentage = (mCurrentProgress / mMaxProgress);
        //绘制内圆弧
        canvas.drawArc(mRectF, 135, 270 * percentage, false, mInnerPaint);
    }

3.3 绘制中间的文字

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mCenterTextRect == null) {
            mCenterTextRect = new Rect();
        }
        mCenterTextPaint.getTextBounds(centerText, 0, centerText.length(), mCenterTextRect);

        //指定中间位置,求基线
        Paint.FontMetricsInt fontMetricsInt = mCenterTextPaint.getFontMetricsInt();
        int baseLine = getHeight() / 2 + (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
        canvas.drawText(centerText, (getWidth() / 2 - mCenterTextRect.width() / 2), baseLine, mCenterTextPaint);
    }

指定中间的位置求基线,详情看:https://www.jianshu.com/p/d06ead5d244b

4.提供一下公共方法

    public void setMaxProgress(int maxProgress) {
        mMaxProgress = maxProgress;
    }

    public void setCurrentProgress(float currentProgress) {
        mCurrentProgress = currentProgress;
        invalidate();
    }

完整项目:stepprogressview

上一篇下一篇

猜你喜欢

热点阅读