自定义View实现进度条

来源:互联网 发布:网络与系统攻击技术 编辑:程序博客网 时间:2024/04/30 18:56

1.自定义属性和属性的使用

<?xml version="1.0" encoding="utf-8"?><resources>    <!-- 声明 -->    <attr name="progress_unreach_color" fomat="color"></attr>    <attr name="progress_unreach_height" fomat="dimension"></attr>    <attr name="progress_reach_color" fomat="color"></attr>    <attr name="progress_reach_height" fomat="dimension"></attr>    <attr name="progress_text_color" fomat="color"></attr>    <attr name="progress_text_size" fomat="dimension"></attr>    <attr name="progress_text_offset" fomat="dimension"></attr>    <!-- 使用 -->    <!-- 线性进度条的使用 -->    <declare-styleable name="HorizontalProgressbarWithProgress">        <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="RoundProgressbarWithProgress">        <attr name="radius" format="dimension"></attr>    </declare-styleable></resources>
protected int dp2px(int dpVal) {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,                dpVal, getResources().getDisplayMetrics());    }    protected int sp2px(int spVal) {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,                spVal, getResources().getDisplayMetrics());    }

2.线形进度条

1.初始化默认值

private static final int DEFAULT_TEXT_SIZE = 10;// sp    private static final int DEFAULT_TEXT_COLOR = 0xFFFC00D1;    private static final int DEFAULT_COLOR_UNREACH = 0XFFD3D6DA;    private static final int DEFAULT_HEIGHT_UNREACH = 2;// dp    private static final int DEFAULT_COLOR_REACH = DEFAULT_TEXT_COLOR;    private static final int DEFAULT_HEIGHT_REACH = 2;// 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_COLOR_UNREACH;    protected int mUnReachHight = dp2px(DEFAULT_HEIGHT_UNREACH);    protected int mReachColor = DEFAULT_COLOR_REACH;    protected int mReachHeight = dp2px(DEFAULT_HEIGHT_REACH);    protected int mTextOffset = dp2px(DEFAULT_TEXT_OFFSET);

2.获取自定义属性

public HorizontalProgressbarWithProgress(Context context,            AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        // TODO Auto-generated constructor stub        // 获取自定义属性        obtainStyledAttrs(attrs);    }
/**     * 获取自定义属性     * @param attrs     */    private void obtainStyledAttrs(AttributeSet attrs) {        // TODO Auto-generated method stub        TypedArray ta = getContext().obtainStyledAttributes(attrs,R.styleable.HorizontalProgressbarWithProgress);        mTextSize = (int) ta.getDimension(R.styleable.HorizontalProgressbarWithProgress_progress_text_size, mTextSize);        mTextColor = ta.getColor(R.styleable.HorizontalProgressbarWithProgress_progress_text_color, mTextColor);        mTextOffset = (int) ta.getDimension(R.styleable.HorizontalProgressbarWithProgress_progress_text_offset, mTextSize);        mUnReachColor = ta.getColor(R.styleable.HorizontalProgressbarWithProgress_progress_unreach_color, mUnReachColor);        mUnReachHight = (int) ta.getDimension(R.styleable.HorizontalProgressbarWithProgress_progress_unreach_height, mUnReachHight);        mReachColor = ta.getColor(R.styleable.HorizontalProgressbarWithProgress_progress_reach_color, mReachColor);        mReachHeight = (int) ta.getDimension(R.styleable.HorizontalProgressbarWithProgress_progress_reach_height,mReachHeight);        ta.recycle();        mPaint.setTextSize(mTextSize);//设置字体的size    }

3.测量

protected synchronized void onMeasure(int widthMeasureSpec,            int heightMeasureSpec) {        // TODO Auto-generated method stub        //int widthMode = MeasureSpec.getMode(widthMeasureSpec);//宽度的模式        //在进度条的情景下 宽度肯定是一个明确的值        int widthVal = MeasureSpec.getSize(widthMeasureSpec);//得到宽度        int height = measureHeight(heightMeasureSpec);//得到高度        setMeasuredDimension(widthVal, height);//设置view的宽高        mRealWidth = getMeasuredWidth()-getPaddingLeft()-getPaddingRight();//绘制区域的宽度    }    private int measureHeight(int heightMeasureSpec) {        // TODO Auto-generated method stub        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, mUnReachHight), Math.abs(textHeight));            if(mode == MeasureSpec.AT_MOST){//测量值不能超过给定的size                result = Math.min(result, size);            }        }        return result;    }

4.绘制

protected synchronized void onDraw(Canvas canvas) {        // TODO Auto-generated method stub        canvas.save();        canvas.translate(getPaddingLeft(), getHeight()/2);        boolean noNeedUnRech = false;        //deaw ReachBar        String text = getProgress()+"%";        int textWidth = (int) mPaint.measureText(text);//获得文本的宽度        float radio = getProgress()*1.0f/getMax();//ReachBar的长度(x%形式)        float progressX = radio*mRealWidth;//理论上 ReachBar的实际长度        if(progressX+textWidth>mRealWidth){//如果ReachBar的长度等于 整个 进度条的长度            progressX = mRealWidth - textWidth; //progressX结束的状态            noNeedUnRech = true;        }        float endX = progressX - mTextOffset/2;//ReachBar的真正的长度(减去百分比数值占据的长度)        if(endX>0){            mPaint.setColor(mReachColor);//画笔设置颜色            mPaint.setStrokeWidth(mReachHeight);//画笔设置高度            canvas.drawLine(0, 0, endX, 0, mPaint);//花一条直线(宽度从0->endx 高度从0->0)        }        //draw text        mPaint.setColor(mTextColor);        int y =(int) -(mPaint.descent()+mPaint.ascent()/2);        canvas.drawText(text, progressX, y, mPaint);        //draw unreachbar        if(!noNeedUnRech){//判断unreachbar是否需要绘制            float start = progressX + mTextOffset/2 + textWidth;            mPaint.setColor(mUnReachColor);            mPaint.setStrokeWidth(mUnReachHight);            canvas.drawLine(start, 0, mRealWidth, 0, mPaint);        }    }

3.圆形进度条

public class RoundProgressbarWithProgress extends        HorizontalProgressbarWithProgress {    private int mRadius = dp2px(30);    private int mMaxPainWidth;    public RoundProgressbarWithProgress(Context context) {        this(context, null);        // TODO Auto-generated constructor stub    }    public RoundProgressbarWithProgress(Context context, AttributeSet attrs) {        this(context, attrs, 0);        // TODO Auto-generated constructor stub    }    public RoundProgressbarWithProgress(Context context, AttributeSet attrs,            int defStyle) {        super(context, attrs, defStyle);        // TODO Auto-generated constructor stub        mReachHeight = (int) (mUnReachHight * 2.5f);        TypedArray ta = context.obtainStyledAttributes(attrs,                R.styleable.RoundProgressbarWithProgress);        mRadius = ta.getDimensionPixelOffset(                R.styleable.RoundProgressbarWithProgress_radius, mRadius);        ta.recycle();        mPaint.setStyle(Style.STROKE);        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStrokeCap(Cap.ROUND);    }    @Override    protected synchronized void onMeasure(int widthMeasureSpec,            int heightMeasureSpec) {        // TODO Auto-generated method stub        mMaxPainWidth = Math.max(mReachHeight, mUnReachHight);        // 默认四个padding 一致        int expect = mRadius * 2 + mMaxPainWidth + getPaddingLeft()                + getPaddingRight();        int width = resolveSize(expect, widthMeasureSpec);        int height = resolveSize(expect, heightMeasureSpec);        int readwidth = Math.min(width, height);        mRadius = (readwidth - getPaddingLeft() - getPaddingRight() - mMaxPainWidth) / 2;        setMeasuredDimension(readwidth, readwidth);    }    @Override    protected synchronized void onDraw(Canvas canvas) {        // TODO Auto-generated method stub        String text = getProgress() + "%";        float textWidth = mPaint.measureText(text);        float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;        canvas.save();        canvas.translate(getPaddingLeft() + mMaxPainWidth / 2, getPaddingTop()                + mMaxPainWidth / 2);        mPaint.setStyle(Style.STROKE);        // draw unreach bar        mPaint.setColor(mUnReachColor);        mPaint.setStrokeWidth(mUnReachHight);        canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);        // draw reach bar        mPaint.setColor(mUnReachColor);        mPaint.setStrokeWidth(mUnReachHight);        float sweepAngle = getProgress()*1.0f/getMax()*360;        canvas.drawArc(new RectF(0, 0, mRadius*2, mRadius*2), 0, sweepAngle, false, mPaint);//绘制一个弧        //draw text        mPaint.setStyle(Style.FILL);        mPaint.setColor(mTextColor);        canvas.drawText(text, mRadius-textWidth/2, mRadius-textHeight, mPaint);        canvas.restore();    }}

4.

https://github.com/Amant-huangqi/progressbar

0 0
原创粉丝点击