【Android】自定义ProgressBar,SeekBar【二】

自定义ProgressBar,SeekBar 第二篇

上一篇链接:http://blog.csdn.net/zhangxiaofan_/article/details/51566455

看到一个网上的进度栏写的挺漂亮,我也来试试吧
一言不合我就贴代码!

效果图如下:
这里写图片描述
目前做出的效果
这里写图片描述
定义如下:

private final int COLOR_RED = 0xFFE32F4F;//源的颜色,红
    private final int COLOR_GREY = 0xFF666666;//目标的颜色,灰
    private RectF mRectFBg;//目标Rect
    private RectF mRectFSrc;//源Rect
    private RectF mRectRound;//圆角矩形Rect
    private Paint mPaint;//画笔
    private Paint mRoundPaint;//画笔
    private Path mDeltaPath;//三角形路径
    private int RADIUS_BIG;//空心的外圆半径
    private int RADIUS_SMALL;//实心的内圆半径
    private int LINE_HEIGHT;//进度线高度
    private int ROUND_RECT_WIDTH;//圆角矩形的宽度
    private int ROUND_RECT_HEIGHT;//圆角矩形的宽度
    private int DELTA_WIDTH;//三角形宽度
    private int DELTA_HEIGHT;//三角形高度
    private int DELTA_SPACE_HEIGHT;//三角形间隔高度
    private float progress;//进度
    private float progressText;//动态文字进度
    private ProgressAnimation animation;//进度动画

初始化

 public ProgressLine2(Context context) {
        super(context);
        init();
    }

    public ProgressLine2(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();

    }

    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mRoundPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        mRoundPaint.setTextSize(30);
    }

onMeasure中

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int measuredHeight = getMeasuredHeight();
        int measuredWidth = getMeasuredWidth();
        if (mRectFBg == null) {
            RADIUS_BIG = (int) (10 * getResources().getDisplayMetrics().density + 0.5f);
            RADIUS_SMALL = RADIUS_BIG >> 1;
            LINE_HEIGHT = (int) (10 * getResources().getDisplayMetrics().density + 0.5f);
            Paint.FontMetrics fm = mRoundPaint.getFontMetrics();
            ROUND_RECT_WIDTH = (int) (mRoundPaint.measureText("100") * 1.5f);
            ROUND_RECT_HEIGHT = (int) ((fm.bottom - fm.top) * 1.5f);
            DELTA_WIDTH = ROUND_RECT_WIDTH / 3;
            DELTA_HEIGHT = ROUND_RECT_WIDTH / 5;
            DELTA_SPACE_HEIGHT = (int) (LINE_HEIGHT/2.5f);
            mPaint.setStrokeWidth(LINE_HEIGHT);

            mRectFBg = new RectF(RADIUS_BIG - RADIUS_SMALL, measuredHeight / 2, measuredWidth - (RADIUS_BIG - RADIUS_SMALL), measuredHeight / 2 + LINE_HEIGHT / 2);
            mRectFSrc = new RectF(mRectFBg);
            mRectFSrc.right = 0;
            mRectRound = new RectF(RADIUS_BIG - RADIUS_SMALL, measuredHeight / 2 - ROUND_RECT_HEIGHT - LINE_HEIGHT / 2 - DELTA_HEIGHT-DELTA_SPACE_HEIGHT, ROUND_RECT_WIDTH + RADIUS_BIG - RADIUS_SMALL, measuredHeight / 2 - LINE_HEIGHT / 2 - DELTA_HEIGHT-DELTA_SPACE_HEIGHT);

            mDeltaPath = new Path();
//            DELTA_HEIGHT/4  是为了让这个三角形往上偏移一点,让一部分重叠在一起
            mDeltaPath.moveTo(mRectRound.left, mRectRound.bottom-DELTA_HEIGHT/4);
            mDeltaPath.lineTo(mRectRound.left + DELTA_WIDTH, mRectRound.bottom-DELTA_HEIGHT/4);
            mDeltaPath.lineTo((mRectRound.left + DELTA_WIDTH) / 2, mRectRound.bottom -DELTA_HEIGHT/4+ DELTA_HEIGHT);
            mDeltaPath.close();
        }
    }

onDraw中

  @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(0x33333333);
        mPaint.setColor(COLOR_GREY);
        canvas.drawLine(mRectFBg.left, mRectFBg.top, mRectFBg.right, getHeight() / 2, mPaint);//绘制目标
        mPaint.setColor(COLOR_RED);
        canvas.drawLine(0, getHeight() / 2, mRectFSrc.right, mRectFSrc.top, mPaint);//绘制源
        mRoundPaint.setColor(0xFFFFFFFF);
        canvas.drawRoundRect(mRectRound, 10, 10, mRoundPaint);//矩形框
        canvas.drawPath(mDeltaPath, mRoundPaint);//三角形
        mRoundPaint.setColor(0xFF000000);
        String str = String.valueOf((int) (progressText * 100));
        Paint.FontMetrics fm = mRoundPaint.getFontMetrics();
        canvas.drawText(str, mRectRound.left + (ROUND_RECT_WIDTH - mRoundPaint.measureText(str)) / 2, mRectRound.bottom - (ROUND_RECT_HEIGHT - (fm.leading - fm.ascent)) / 2, mRoundPaint);//文字
    }

设置进度的方法


    public void setProgress(float progress) {
        this.progress = progress;
        if (animation == null) {
            animation = new ProgressAnimation();
            animation.setDuration(3000);
            animation.setInterpolator(new AccelerateDecelerateInterpolator());
            animation.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {

                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
        }
        startAnimation(animation);
    }

主要的计算逻辑在这个动画类中

 private class ProgressAnimation extends Animation {
        float offsetX;
        float offsetY;

        public ProgressAnimation() {
            offsetY = mRectRound.bottom + ROUND_RECT_WIDTH / 6;
            offsetX = RADIUS_BIG - RADIUS_SMALL;
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            progressText = interpolatedTime * progress;
            mRectFSrc.right = (mRectFBg.right - RADIUS_SMALL * 2) * interpolatedTime * progress;
            mRectFBg.left = mRectFSrc.right;
            mRectRound.left = RADIUS_BIG - RADIUS_SMALL + (getWidth() - ROUND_RECT_WIDTH) * interpolatedTime;
            mRectRound.right = RADIUS_BIG - RADIUS_SMALL + (getWidth() - ROUND_RECT_WIDTH) * interpolatedTime + ROUND_RECT_WIDTH;
            if (interpolatedTime < 0.4f) {
                interpolatedTime *= 10.0f / 4;
                mRectFSrc.top = getHeight() / 2 + (getHeight() - LINE_HEIGHT) / 2 * interpolatedTime;
                mRectFBg.top = getHeight() / 2 + (getHeight() - LINE_HEIGHT) / 2 * interpolatedTime;
                mRectRound.top = getHeight() / 2 - ROUND_RECT_HEIGHT - LINE_HEIGHT / 2 - DELTA_HEIGHT-DELTA_SPACE_HEIGHT + getHeight() / 2 * interpolatedTime;
                mRectRound.bottom = getHeight() / 2 - LINE_HEIGHT / 2 - DELTA_HEIGHT-DELTA_SPACE_HEIGHT + getHeight() / 2 * interpolatedTime;
                mDeltaPath.offset(mRectRound.left - offsetX, mRectRound.bottom + ROUND_RECT_WIDTH / 6- offsetY);
                offsetX = mRectRound.left;
                offsetY = mRectRound.bottom + ROUND_RECT_WIDTH / 6;
            } else {
                interpolatedTime = (interpolatedTime - 0.4f) * 10.0f / 6;
                mRectFSrc.top = getHeight() - LINE_HEIGHT / 2 - (getHeight() - LINE_HEIGHT) / 2 * interpolatedTime;
                mRectFBg.top = getHeight() - LINE_HEIGHT / 2 - (getHeight() - LINE_HEIGHT) / 2 * interpolatedTime;
                mRectRound.top = getHeight() - ROUND_RECT_HEIGHT - LINE_HEIGHT / 2 - DELTA_HEIGHT -DELTA_SPACE_HEIGHT- (getHeight() / 2) * interpolatedTime;
                mRectRound.bottom = getHeight() - LINE_HEIGHT / 2 - DELTA_HEIGHT -DELTA_SPACE_HEIGHT- getHeight() / 2 * interpolatedTime;
                mDeltaPath.offset(mRectRound.left - offsetX, mRectRound.bottom + ROUND_RECT_WIDTH / 6- offsetY);
                offsetX = mRectRound.left;
                offsetY = mRectRound.bottom + ROUND_RECT_WIDTH / 6;
            }
            invalidate();
        }
    }

最后总结:
这个其实还没有完全完成,移动的时候 矩形下面的三角形偏移处理没有做处理,和原图的效果不一致,且在移动中整个矩形和底下的线的纵轴偏移没有保持不变.
只是我已经对这个类不感兴趣了,剩余的你们自己完成吧

代码下载:http://download.csdn.net/detail/zhangxiaofan_/9543264

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值