<Android> 打造自己的进度条

横向的进度条

package com.sdp.panda.myviewapp.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ProgressBar;

import com.sdp.panda.myviewapp.R;

/**
 * Created by 80926 on 2016/11/24.
 */

public class MyHorizontalProgressBar extends ProgressBar {
    //设置成员变量的默认值
    private static final int DEFAULT_TEXT_SIZE = 10;//sp
    private static final int DEFAULT_TEXT_COLOR = Color.BLACK;
    private static final int DEFAULT_UNREACH_COLOR = 0XFFD3D6DA;
    private static final int DEFAULT_UNREACH_HEIGHT = 3;//dp
    private static final int DEFAULT_REACH_COLOR = DEFAULT_TEXT_COLOR;
    private static final int DEFAULT_REACH_HEIGHT = 4;//dp
    private static final int DEFAULT_TEXT_OFFSET = 10;//dp

    protected int mTextSize = sp2px(DEFAULT_TEXT_SIZE);
    protected int mTextColor = DEFAULT_TEXT_COLOR;
    protected int mUnReachColor = DEFAULT_UNREACH_COLOR;
    protected int mUnReachHeight = dp2px(DEFAULT_UNREACH_HEIGHT);
    protected int mReachColor = DEFAULT_REACH_COLOR;
    protected int mReachHeight = dp2px(DEFAULT_REACH_HEIGHT);
    protected int mTextOffset = dp2px(DEFAULT_TEXT_OFFSET);

    private Paint mPaint;
    private int mRealWidth;//真正的宽度除去padding
    private TypedArray mTA;

    public MyHorizontalProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    public MyHorizontalProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyHorizontalProgressBar(Context context) {
        this(context, null);
    }

    private void init(Context context, AttributeSet attrs) {
        mPaint = new Paint();
        obtainStyledAttrs(attrs);//获取属性array,对成员变量初始化

    }

    private void obtainStyledAttrs(AttributeSet attrs) {
        mTA = getContext().obtainStyledAttributes(attrs, R.styleable.MyHorizontalProgressBar);
        mTextSize = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_text_size, mTextSize);
        mTextColor = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_text_color, mTextColor);
        mTextOffset = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_text_offset, mTextOffset);
        mUnReachColor = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_unreach_color, mUnReachColor);
        mUnReachHeight = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_unreach_height, mUnReachHeight);
        mReachColor = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_reach_color, mReachColor);
        mReachHeight = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_reach_height, mReachHeight);
        mTA.recycle();
        mPaint.setTextSize(mTextSize);
    }

    //转换sp、dp.px
    protected int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
    }

    protected int sp2px(int sp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        //宽度必须是指定值
        int widthVal = MeasureSpec.getSize(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(widthVal, height);
        mRealWidth = getMeasuredWidth() - getPaddingRight() - getPaddingLeft();
    }

    private int measureHeight(int heightMeasureSpec) {
        int result = 0;
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {//精确值
            result = size;
        } else {
            int textHeight = (int) (mPaint.descent() - mPaint.ascent());
            result = getPaddingTop() + getPaddingBottom() +
                    Math.max(Math.max(mReachHeight, mUnReachHeight), Math.abs(textHeight));
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }
        return result;
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        canvas.save();
        canvas.translate(getPaddingLeft(), getHeight() / 2);
        //绘制reachBar
        boolean noNeedUnReach = false;//是否需要绘制
        String text = getProgress() + "%";
        int textWidth = (int) mPaint.measureText(text);
        float radio = getProgress() * 1.0f / getMax();//百分比
        float progressX = radio * mRealWidth;
        if (progressX + textWidth > mRealWidth) {
            progressX = mRealWidth - textWidth;
            noNeedUnReach = true;
        }
        float endX = progressX - mTextOffset / 2;
        if (endX > 0) {
            mPaint.setColor(mReachColor);
            mPaint.setStrokeWidth(mReachHeight);
            canvas.drawLine(0, 0, endX, 0, mPaint);
        }

        //drawText
        mPaint.setColor(mTextColor);
        int textHeightCenter = (int) (-(mPaint.descent() + mPaint.ascent()) / 2);
        canvas.drawText(text, progressX, textHeightCenter, mPaint);

        //绘制unReachBar
        if (!noNeedUnReach) {
            float start = progressX + mTextOffset / 2 + textWidth;
            mPaint.setColor(mUnReachColor);
            mPaint.setStrokeWidth(mUnReachHeight);
            canvas.drawLine(start, 0, mRealWidth, 0, mPaint);
        }
        canvas.restore();
    }
}

圆形的进度条

package com.sdp.panda.myviewapp.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ProgressBar;

import com.sdp.panda.myviewapp.R;

/**
 * Created by 80926 on 2016/11/25.
 */

public class MyRoundProgressBar extends ProgressBar {
    private static final int DEFAULT_TEXT_SIZE = 10;//sp
    private static final int DEFAULT_TEXT_COLOR = Color.RED;
    private static final int DEFAULT_UNREACH_COLOR = Color.BLUE;
    private static final int DEFAULT_UNREACH_HEIGHT = 3;//dp
    private static final int DEFAULT_REACH_COLOR = DEFAULT_TEXT_COLOR;
    private static final int DEFAULT_REACH_HEIGHT = 4;//dp
    private static final int DEFAULT_TEXT_OFFSET = 10;//dp

    protected int mTextSize = sp2px(DEFAULT_TEXT_SIZE);
    protected int mTextColor = DEFAULT_TEXT_COLOR;
    protected int mUnReachColor = DEFAULT_UNREACH_COLOR;
    protected int mUnReachHeight = dp2px(DEFAULT_UNREACH_HEIGHT);
    protected int mReachColor = DEFAULT_REACH_COLOR;
    protected int mReachHeight = dp2px(DEFAULT_REACH_HEIGHT);
    protected int mTextOffset = dp2px(DEFAULT_TEXT_OFFSET);

    private Paint mPaint;
    private int mRadius = dp2px(30);//榛樿鍗婂緞涓?0dp
    private int mMaxPaintWidth;//鏈€澶х殑瀹藉害

    public MyRoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    public MyRoundProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyRoundProgressBar(Context context) {
        this(context, null);
    }

    private void init(Context context, AttributeSet attrs) {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//鎶楅敮榻?
        mReachHeight = (int) (mUnReachHeight * 2.0f);
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyRoundProgressBar);
        TypedArray mTA = context.obtainStyledAttributes(attrs, R.styleable.MyHorizontalProgressBar);
        mRadius = (int) ta.getDimension(R.styleable.MyRoundProgressBar_radius, mRadius);
        mTextSize = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_text_size, mTextSize);
        mTextColor = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_text_color, mTextColor);
        mTextOffset = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_text_offset, mTextOffset);
        mUnReachColor = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_unreach_color, mUnReachColor);
        mUnReachHeight = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_unreach_height, mUnReachHeight);
        mReachColor = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_reach_color, mReachColor);
        mReachHeight = (int) mTA.getDimension(R.styleable.MyHorizontalProgressBar_progress_reach_height, mReachHeight);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setDither(true);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setTextSize(mTextSize);
    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mMaxPaintWidth = Math.max(mReachHeight, mUnReachHeight);
        int expect = mRadius * 2 + mMaxPaintWidth + getPaddingLeft() + getPaddingRight();
        int width = resolveSize(expect, widthMeasureSpec);
        int height = resolveSize(expect, heightMeasureSpec);
        int realWidth = Math.min(width, height);
        mRadius = (realWidth - getPaddingLeft() - getPaddingRight() - mMaxPaintWidth) / 2;
        setMeasuredDimension(realWidth, realWidth);
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        String text = getProgress() + "%";
        float textWidth = mPaint.measureText(text);
        float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;

        canvas.save();
        canvas.translate(getPaddingLeft() + mMaxPaintWidth / 2, getPaddingTop() + mMaxPaintWidth / 2);

        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(mUnReachColor);
        mPaint.setStrokeWidth(mUnReachHeight);
        canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);

        mPaint.setColor(mReachColor);
        mPaint.setStrokeWidth(mReachHeight);
        float sweepAngle = getProgress() * 1.0f / getMax() * 360;
        canvas.drawArc(0,0,mRadius*2,mRadius*2,0,sweepAngle,false,mPaint);
//        canvas.drawArc(new RectF(0, 0, mRadius * 2, mRadius * 2), 0, sweepAngle, false, mPaint);

        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setStrokeWidth(mTextSize);
        mPaint.setColor(mTextColor);
        canvas.drawText(text, mRadius - textWidth / 2, mRadius - textHeight / 2, mPaint);
        canvas.restore();
    }

    protected int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
    }
    protected int sp2px(int sp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
    }
}

使用的xml文件

    res文件夹下的arrts.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 这里进行声明属性-->
    <attr name="progress_unreach_color" format="color"></attr>
    <attr name="progress_unreach_height" format="dimension"></attr>
    <attr name="progress_reach_color" format="color"></attr>
    <attr name="progress_reach_height" format="dimension"></attr>
    <attr name="progress_text_color" format="color"></attr>
    <attr name="progress_text_size" format="dimension"></attr>
    <attr name="progress_text_offset" format="dimension"></attr>
    <!-- 这里使用属性-->
    <declare-styleable name="MyHorizontalProgressBar">
        <attr name="progress_unreach_color"></attr>
        <attr name="progress_unreach_height"></attr>
        <attr name="progress_reach_color"></attr>
        <attr name="progress_reach_height"></attr>
        <attr name="progress_text_color"></attr>
        <attr name="progress_text_size"></attr>
        <attr name="progress_text_offset"></attr>
    </declare-styleable>
    <declare-styleable name="MyRoundProgressBar">
        <attr name="radius" format="dimension"></attr>
    </declare-styleable>
</resources>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值