随记11——我的简单的自定义View之进度条

来源:互联网 发布:linux wps 编辑:程序博客网 时间:2024/06/02 03:02


女神镇楼

一共两个进度条,一个是水平的进度条,一个是圆形的进度条,效果如下:

先说圆形进度条,继承TextView,有几个自定义属性:

    <!--圆形进度条-->    <declare-styleable name="circleProgressView">        <attr name="strokeBgColor" format="color"/>        <attr name="strokeColor" format="color"/>        <attr name="strokeWidth" format="dimension"/>        <attr name="progress" format="integer"/>        <attr name="fromAngle" format="integer"/>        <attr name="isCapRound" format="boolean"/>    </declare-styleable>
strokeBgColor圆环的背景颜色(默认ff0000),strokeColor圆环颜色(默认f6f6f6),strokeWidth圆环宽度(默认10px),progress进度(默认0),fromAngle起始角度(默认0,定义从正上方为0度),isCapRound圆环进度起末是否为圆形(默认为true)。用法如下:

    <com.bjl.mypractice.view.CircleProgressView        android:id="@+id/circleProgressView"        android:layout_width="200dp"        android:layout_height="200dp"        app:strokeBgColor="@color/colorPrimary"        app:strokeColor="@color/color_ff0000"        app:strokeWidth="5dp"        app:progress="20"        app:fromAngle="0"        android:textColor="@color/color_ff0000"        android:textSize="16sp"        android:text="张三"        android:gravity="center"/>
View代码如下:

/** * Created by Administrator on 2017/12/18. * 圆形进度条 */public class CircleProgressView extends android.support.v7.widget.AppCompatTextView {    /**     * 圆环默认宽度     */    private float defaultStrokeWidth = 10;    /**     * 进度值0~100     */    private int mProgress;    /**     * 起始角度0~360     * -90为正上方     * 0为3点位置     */    private int fromAngle = 0;////    private int textSize = 14;//    private int textColor;//默认666666;//    private String text = "张三";    private boolean isCapRound = true;//进度是开头和结尾否是圆形的    private Paint mPaint;    private Paint mBgPaint;    private Paint mTextPaint;    RectF ovl;//圆环内环绘制的区域    private boolean isProgressing = false;//是否正在绘制进度 防止线程多重绘制    public CircleProgressView(Context context) {        this(context, null);    }    public CircleProgressView(Context context, @Nullable AttributeSet attrs) {        this(context, attrs, 0);    }    public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(attrs);    }    private void init(AttributeSet attrs) {        mPaint = new Paint();        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.STROKE);        mBgPaint = new Paint();        mBgPaint.setAntiAlias(true);        mBgPaint.setDither(true);        mBgPaint.setStyle(Paint.Style.STROKE);        mTextPaint = new Paint();        mTextPaint.setAntiAlias(true);        mTextPaint.setDither(true);        mTextPaint.setStyle(Paint.Style.FILL);        int strokeColor = Color.parseColor("#ff0000");        int strokeBgColor = Color.parseColor("#f6f6f6");        if (attrs != null){            TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.circleProgressView);            strokeBgColor = array.getColor(R.styleable.circleProgressView_strokeBgColor, Color.parseColor("#f6f6f6"));            strokeColor = array.getColor(R.styleable.circleProgressView_strokeColor, Color.parseColor("#ff0000"));            defaultStrokeWidth = (int) array.getDimension(R.styleable.circleProgressView_strokeWidth, 10);            mProgress = array.getInteger(R.styleable.circleProgressView_progress, 0);            fromAngle = array.getInteger(R.styleable.circleProgressView_fromAngle, 0);            isCapRound = array.getBoolean(R.styleable.circleProgressView_isCapRound, true);            if (fromAngle < 0){                fromAngle = 0;            }else if (fromAngle > 360){                fromAngle = -90 + fromAngle%360;            }            array.recycle();        }        if (isCapRound){            mPaint.setStrokeCap(Paint.Cap.ROUND);        }        mPaint.setStrokeWidth(defaultStrokeWidth);        mPaint.setColor(strokeColor);        mBgPaint.setStrokeWidth(defaultStrokeWidth);        mBgPaint.setColor(strokeBgColor);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int width = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int height = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        setMeasuredDimension(getDefaultSize(width, widthMeasureSpec), getDefaultSize(height, heightMeasureSpec));        ovl = new RectF(0 + defaultStrokeWidth/2, 0  + defaultStrokeWidth/2, getMeasuredWidth() -  + defaultStrokeWidth/2, getMeasuredHeight() -  + defaultStrokeWidth/2);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);//        ovl = new RectF(0 + defaultStrokeWidth/2, 0  + defaultStrokeWidth/2, getMeasuredWidth() -  + defaultStrokeWidth/2, getMeasuredHeight() -  + defaultStrokeWidth/2);        canvas.drawArc(ovl, fromAngle - 90, 360, false, mBgPaint);        canvas.drawArc(ovl, fromAngle - 90, 360 * mProgress/100, false, mPaint);//        canvas.drawText(text, getWidth()/2, getHeight()/2, mTextPaint);    }    public void setProgress(int progress){        if (progress <= 0){            progress = 0;            mProgress  = 0;            postInvalidate();        }else if (progress > 100){            progress = 100;        }        //解决多个线程同时修改界面的问题        if (isProgressing)            isProgressing = false;        final int finalProgress = progress;        new Handler().postDelayed(new Runnable() {            @Override            public void run() {                isProgressing = true;                new Thread() {                    @Override                    public void run() {                        super.run();                        //防止上一个线程的影响                        for (int i = 0; i < finalProgress; i++) {                            mProgress = i;                            postInvalidate();                            try {                                Thread.sleep(30);                            } catch (InterruptedException e) {                                e.printStackTrace();                            }                            if (!isProgressing) {                                break;                            }                        }                        isProgressing = false;                    }                }.start();            }        }, 50);    }}

下面是长形进度条,同圆形进度条差不多。

自定义属性如下:

    <!--长形进度条-->    <declare-styleable name="horProgressView">                <attr name="progressColor" format="color"/>        <attr name="progressBgColor" format="color"/>        <attr name="progress"/>        <attr name="isCapRound"/>    </declare-styleable>
progressColor进度颜色(默认ff0000),progressBgColor进度背景颜色(默认f6f6f6),progress进度(默认0),isCapRound圆角(默认true)

用法同CricleProgressView。代码如下:

/** * Created by Administrator on 2017/12/19. * 水平进度条 */public class HorProgressView extends View {    private int strokeWidth;//进度条的高度    private Paint mProgressPaint;    private Paint mBgPaint;    private int mProgress;//进度    private int progressColor;//进度颜色 默认ff0000    private int progressBgColor;//进度背景颜色 默认f6f6f6    private boolean isCapRound = true;//进度是开头和结尾否是圆形的    private boolean isProgressing = false;//是否正在绘制进度 防止线程多重绘制    public HorProgressView(Context context) {        this(context, null);    }    public HorProgressView(Context context, @Nullable AttributeSet attrs) {        this(context, attrs, 0);    }    public HorProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(attrs);    }    private void init(AttributeSet attrs){        mProgressPaint = new Paint();        mProgressPaint.setAntiAlias(true);        mProgressPaint.setDither(false);//        mProgressPaint.setStyle(Paint.Style.STROKE);//        mProgressPaint.setStrokeCap(Paint.Cap.ROUND);//        mBgPaint = new Paint();//        mBgPaint.setAntiAlias(true);//        mBgPaint.setDither(false);////        mBgPaint.setStyle(Paint.Style.STROKE);//        mBgPaint.setStrokeCap(Paint.Cap.ROUND);        mBgPaint = new Paint();        mBgPaint.setAntiAlias(true);        mBgPaint.setDither(false);//        mBgPaint.setStyle(Paint.Style.FILL);//        mBgPaint.setStrokeCap(Paint.Cap.ROUND);        if (attrs != null){            TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.horProgressView);            progressColor = array.getColor(R.styleable.horProgressView_progressColor, Color.parseColor("#ff0000"));            progressBgColor = array.getColor(R.styleable.horProgressView_progressBgColor, Color.parseColor("#f6f6f6"));            mProgress = array.getInteger(R.styleable.horProgressView_progress, 0);            isCapRound = array.getBoolean(R.styleable.horProgressView_isCapRound, true);            if (mProgress < 0){                mProgress = 0;            }else if (mProgress > 100){                mProgress = 100;            }            array.recycle();        }        if (isCapRound){            mProgressPaint.setStrokeCap(Paint.Cap.ROUND);            mBgPaint.setStrokeCap(Paint.Cap.ROUND);        }        mProgressPaint.setColor(progressColor);        mBgPaint.setColor(progressBgColor);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int width = MeasureSpec.getSize(widthMeasureSpec);        int height = MeasureSpec.getSize(heightMeasureSpec);//        int heightMode = MeasureSpec.getMode(heightMeasureSpec);//        if (heightMode == MeasureSpec.EXACTLY)        setMeasuredDimension(getDefaultSize(width, widthMeasureSpec), getDefaultSize(height, heightMeasureSpec));        strokeWidth = getMeasuredHeight();        mProgressPaint.setStrokeWidth(getMeasuredHeight());        mBgPaint.setStrokeWidth(getMeasuredHeight());    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (isCapRound){            //有圆角            canvas.drawLine(getHeight()/2, getHeight()/2, getWidth() - getHeight()/2, getHeight()/2, mBgPaint);//        canvas.drawRect(0, 0, getWidth(), getHeight(),mBgPaint);            canvas.drawLine(getHeight()/2, getHeight()/2, (getWidth() - getHeight()) * mProgress / 100 + getHeight()/2, getHeight()/2, mProgressPaint);        }else {            canvas.drawLine(0, getHeight()/2, getWidth(), getHeight()/2, mBgPaint);            canvas.drawLine(0, getHeight()/2, getWidth() * mProgress / 100 , getHeight()/2, mProgressPaint);        }    }    public void setProgress(int progress) {        if (progress <= 0){            progress = 0;            mProgress  = 0;            postInvalidate();        }else if (progress > 100){            progress = 100;        }        //解决多个线程同时修改界面的问题        if (isProgressing)            isProgressing = false;        final int finalProgress = progress;        new Handler().postDelayed(new Runnable() {            @Override            public void run() {                isProgressing = true;                new Thread() {                    @Override                    public void run() {                        super.run();                        //防止上一个线程的影响                        for (int i = 0; i < finalProgress; i++) {                            mProgress = i;                            postInvalidate();                            try {                                Thread.sleep(30);                            } catch (InterruptedException e) {                                e.printStackTrace();                            }                            if (!isProgressing) {                                break;                            }                        }                        isProgressing = false;                    }                }.start();            }        }, 50);    }}
下一篇是自定义SeekBar,还有一个我个人比较满意的ColorLoadingView。
本期代码下载地址:回来跟下面的SeekBar及ColorLoadingView一起发吧。

阅读全文
0 0