自定义view下载进度条展示

自定义视图的实现方式大概有三种,组合控件,继承控件和自绘控件

组合控件:使用时只用系统原生的各个控件就行了,例如实际开发中经常会自己定义一个titlebar,需要一个返回键和title,这样的就是组合控件

继承控件:继承系统的原生控件,在他的基础上再添加一些新功能,例如登陆时的验证码60秒倒计时,我们就可以去自定义一个button去实现这个功能

自绘控件:页面上展示的东西都是通过代码自己去绘制出来的


这次带来的是通过自定义view去实现下载时圆环进度以及进度数的一个progressView

其余的倒不用管,想要绘制视图必须在的onDraw();方法中。


先看下最终实现的效果




我们先去继承一个视图,然后实现它的构造方法


public class ProgressBarView extends View {

    public ProgressBarView(Context context) {
        super(context);
    }

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

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

然后再值目录下创建一个attrs.xml文件

 <declare-styleable name="CirclesProgressBar">

        <attr name="circlesWidth" format="dimension" />
        <attr name="circlesColor" format="color" />
        <attr name="textCrude" format="dimension" />
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
        <attr name="currentProgressColor" format="color" />
        <attr name="currentProgress" format="integer" />
        <attr name="isPercent" format="boolean" />
        <attr name="style" format="integer" />
        <attr name="currentScheduleWidth" format="dimension" />
 </declare-styleable>



这个是用来初始化一些变量的,例如进度初始化的颜色,字体颜色,字体大小之类的,而且可以直接在xml中引用


//接下来在视图中写一些必须要的变量以及两种不同风格的风格

    //空心
    public static final int STROKE = 1;
    //实心
    public static final int FILL = 0;


    private Paint mPaint;
    private int style;

    //圆环的宽度
    private float circlesWidth;
    //圆环的颜色
    private int circlesColor;
    //进度字体的粗细程度
    private float textCrude;
    //字体颜色
    private int textColor;
    //字体大小
    private float textSize;
    //设置字体
    private Typeface mTypeface;
    //当前进度
    private int currentProgress;
    //进度颜色
    private int currentProgressColor;
    //进度圆环的宽度
    private float currentScheduleWidth;
    //是否显示百分比
    private boolean isPercent;



接着去初始化这些变量,指定一些数据,例如字体的大小圆环的颜色之类的

    private void init(Context context, AttributeSet attrs) {

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.CirclesProgressBar);


        //初始化圆环变量
        circlesWidth = mTypedArray.getDimension(R.styleable.CirclesProgressBar_circlesWidth, ProgressDefaults.CIRCLES_WIDTH);
        circlesColor = mTypedArray.getColor(R.styleable.CirclesProgressBar_circlesColor, ProgressDefaults.CIRCLES_COLOR);
        textCrude = mTypedArray.getDimension(R.styleable.CirclesProgressBar_textCrude, ProgressDefaults.TEXT_CRUDE);
        textColor = mTypedArray.getColor(R.styleable.CirclesProgressBar_textColor, ProgressDefaults.TEXT_COLOR);
        textSize = mTypedArray.getDimension(R.styleable.CirclesProgressBar_textSize, ProgressDefaults.TEXT_SIZE);
        currentProgress = mTypedArray.getInt(R.styleable.CirclesProgressBar_currentProgress, ProgressDefaults.CURRENT_PROGRESS);
        currentProgressColor = mTypedArray.getColor(R.styleable.CirclesProgressBar_currentProgressColor, ProgressDefaults.CURRENT_PROGRESS_COLOR);
        isPercent = mTypedArray.getBoolean(R.styleable.CirclesProgressBar_isPercent, ProgressDefaults.IS_PERCENT);
        style = mTypedArray.getInt(R.styleable.CirclesProgressBar_style, ProgressDefaults.STYLE);
        currentScheduleWidth = mTypedArray.getDimension(R.styleable.CirclesProgressBar_currentScheduleWidth, ProgressDefaults.CURRENT_SCHEDULE_WIDTH);

        mTypedArray.recycle();
    }

然后重写的onDraw();方法去绘制我们需要的圆环以及进度数据

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int anInt = getWidth() / 2;
        int circlesRadius = (int) (anInt - circlesWidth / 2);//半径


        //圆环
        mPaint.setColor(circlesColor);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(circlesWidth);
        canvas.drawCircle(anInt, anInt, circlesRadius, mPaint);

        //百分比
        if (isPercent && style == STROKE) {
            mPaint.setStrokeWidth(textCrude);
            mPaint.setColor(textColor);
            mPaint.setTextSize(textSize);
            mPaint.setTypeface(mTypeface);
            int percent = (int) (((float) currentProgress / (float) ProgressDefaults.PROGRESS_BAR_MAX) * 100);
            float textWidth = mPaint.measureText(percent + "%");
            canvas.drawText(percent + "%", anInt - textWidth / 2, anInt + textSize / 2, mPaint);
        }


        //进度的圆环
        mPaint.setColor(currentProgressColor);
        mPaint.setStrokeWidth(currentScheduleWidth);
        RectF rectF = new RectF(anInt - circlesRadius, anInt - circlesRadius, anInt + circlesRadius, anInt + circlesRadius);

        //选择风格
        switch (style) {

            case STROKE:
                if (currentProgress != 0) {
                    mPaint.setStyle(Paint.Style.STROKE);
                    canvas.drawArc(rectF, 0, 360 * currentProgress / ProgressDefaults.PROGRESS_BAR_MAX, false, mPaint);
                }
                break;
            case FILL:
                if (currentProgress != 0) {
                    mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
                    canvas.drawArc(rectF, 0, 360 * currentProgress / ProgressDefaults.PROGRESS_BAR_MAX, true, mPaint);
                }
                break;
        }
        Log.i("onDraw---->", "onDraw current");
    }



然后为了能在代码中方便的改变一些数据还需要一些set,get方法。

整体的代码如下:


public class ProgressBarView extends View {

    //空心
    public static final int STROKE = 1;
    //实心
    public static final int FILL = 0;


    private Paint mPaint;
    private int style;

    //圆环的宽度
    private float circlesWidth;
    //圆环的颜色
    private int circlesColor;
    //进度字体的粗细程度
    private float textCrude;
    //字体颜色
    private int textColor;
    //字体大小
    private float textSize;
    //设置字体
    private Typeface mTypeface;
    //当前进度
    private int currentProgress;
    //进度颜色
    private int currentProgressColor;
    //进度圆环的宽度
    private float currentScheduleWidth;
    //是否显示百分比
    private boolean isPercent;


    public ProgressBarView(Context context) {
        super(context);
    }

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

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

    private void init(Context context, AttributeSet attrs) {

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.CirclesProgressBar);


        //初始化圆环变量
        circlesWidth = mTypedArray.getDimension(R.styleable.CirclesProgressBar_circlesWidth, ProgressDefaults.CIRCLES_WIDTH);
        circlesColor = mTypedArray.getColor(R.styleable.CirclesProgressBar_circlesColor, ProgressDefaults.CIRCLES_COLOR);
        textCrude = mTypedArray.getDimension(R.styleable.CirclesProgressBar_textCrude, ProgressDefaults.TEXT_CRUDE);
        textColor = mTypedArray.getColor(R.styleable.CirclesProgressBar_textColor, ProgressDefaults.TEXT_COLOR);
        textSize = mTypedArray.getDimension(R.styleable.CirclesProgressBar_textSize, ProgressDefaults.TEXT_SIZE);
        currentProgress = mTypedArray.getInt(R.styleable.CirclesProgressBar_currentProgress, ProgressDefaults.CURRENT_PROGRESS);
        currentProgressColor = mTypedArray.getColor(R.styleable.CirclesProgressBar_currentProgressColor, ProgressDefaults.CURRENT_PROGRESS_COLOR);
        isPercent = mTypedArray.getBoolean(R.styleable.CirclesProgressBar_isPercent, ProgressDefaults.IS_PERCENT);
        style = mTypedArray.getInt(R.styleable.CirclesProgressBar_style, ProgressDefaults.STYLE);
        currentScheduleWidth = mTypedArray.getDimension(R.styleable.CirclesProgressBar_currentScheduleWidth, ProgressDefaults.CURRENT_SCHEDULE_WIDTH);

        mTypedArray.recycle();
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int anInt = getWidth() / 2;
        int circlesRadius = (int) (anInt - circlesWidth / 2);//半径


        //圆环
        mPaint.setColor(circlesColor);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(circlesWidth);
        canvas.drawCircle(anInt, anInt, circlesRadius, mPaint);

        //百分比
        if (isPercent && style == STROKE) {
            mPaint.setStrokeWidth(textCrude);
            mPaint.setColor(textColor);
            mPaint.setTextSize(textSize);
            mPaint.setTypeface(mTypeface);
            int percent = (int) (((float) currentProgress / (float) ProgressDefaults.PROGRESS_BAR_MAX) * 100);
            float textWidth = mPaint.measureText(percent + "%");
            canvas.drawText(percent + "%", anInt - textWidth / 2, anInt + textSize / 2, mPaint);
        }


        //进度的圆环
        mPaint.setColor(currentProgressColor);
        mPaint.setStrokeWidth(currentScheduleWidth);
        RectF rectF = new RectF(anInt - circlesRadius, anInt - circlesRadius, anInt + circlesRadius, anInt + circlesRadius);

        //选择风格
        switch (style) {

            case STROKE:
                if (currentProgress != 0) {
                    mPaint.setStyle(Paint.Style.STROKE);
                    canvas.drawArc(rectF, 0, 360 * currentProgress / ProgressDefaults.PROGRESS_BAR_MAX, false, mPaint);
                }
                break;
            case FILL:
                if (currentProgress != 0) {
                    mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
                    canvas.drawArc(rectF, 0, 360 * currentProgress / ProgressDefaults.PROGRESS_BAR_MAX, true, mPaint);
                }
                break;
        }
        Log.i("onDraw---->", "onDraw current");
    }


    public synchronized void setCurrentProgress(int currentProgress) {
        if (currentProgress < ProgressDefaults.CURRENT_PROGRESS) {
            currentProgress = ProgressDefaults.CURRENT_PROGRESS;
        }
        if (currentProgress > ProgressDefaults.PROGRESS_BAR_MAX) {
            currentProgress = ProgressDefaults.PROGRESS_BAR_MAX;
        }
        if (currentProgress <= ProgressDefaults.PROGRESS_BAR_MAX) {
            this.currentProgress = currentProgress;
            postInvalidate();
        }
    }

    public synchronized float getCurrentProgress() {
        return currentProgress;
    }


    public void setScheduleWidth(float currentScheduleWidth) {
        this.currentScheduleWidth = currentScheduleWidth;
    }

    public float getScheduleWidth() {
        return currentScheduleWidth;
    }

    public void setStyle(int style) {
        this.style = style;
    }

    public int getStyle() {
        return style;
    }

    public void setPercent(boolean isPercent) {
        this.isPercent = isPercent;
    }

    public boolean getPercent() {
        return isPercent;
    }

    public void setCurrentProgressColor(int currentProgressColor) {
        if (currentProgressColor < ProgressDefaults.MIN) {
            currentProgressColor = ProgressDefaults.CURRENT_PROGRESS_COLOR;
        }
        this.currentProgressColor = currentProgressColor;
    }

    public int getCurrentProgressColor() {
        return currentProgressColor;
    }

    public void setTypeface(Typeface typeface) {
        this.mTypeface = typeface;
    }

    public void setCirclesWidth(float circlesWidth) {
        if (circlesWidth < ProgressDefaults.MIN) {
            circlesWidth = ProgressDefaults.CIRCLES_WIDTH;
        }
        this.circlesWidth = circlesWidth;
    }

    public float getCirclesWidth() {
        return circlesWidth;
    }

    public void setCirclesColor(int circlesColor) {
        if (circlesColor < ProgressDefaults.MIN) {
            circlesColor = ProgressDefaults.CIRCLES_COLOR;
        }
        this.circlesColor = circlesColor;
    }

    public int getCirclesColor() {
        return circlesColor;
    }

    public void setTextCrude(float textCrude) {
        if (textCrude < ProgressDefaults.MIN) {
            textCrude = ProgressDefaults.TEXT_CRUDE;
        }
        this.textCrude = textCrude;
    }

    public float getTextCrude() {
        return textCrude;
    }

    public void setTextColor(int textColor) {
        if (textColor < ProgressDefaults.MIN) {
            textColor = ProgressDefaults.TEXT_COLOR;
        }
        this.textColor = textColor;
    }

    public int getTextColor() {
        return textColor;
    }

    public void setTextSize(float textSize) {
        if (textSize < ProgressDefaults.MIN) {
            textSize = ProgressDefaults.TEXT_SIZE;
        }
        this.textSize = textSize;
    }
}


ProgressDefaults这个类主要的就是我们初始化的一些变量

public class ProgressDefaults {


    /**
     * 判断数据的最小值
     */
    public static final int MIN = 1;

    /**
     * 最大进度
     */
    public static final int PROGRESS_BAR_MAX = 100;

    /**
     * 默认进度
     */
    public static final int CURRENT_PROGRESS = 0;

    /**
     * 默认圆环宽度
     */
    public static final float CIRCLES_WIDTH = 5;
    /**
     * 默认进度宽度
     */
    public static final float CURRENT_SCHEDULE_WIDTH = 6;

    /**
     * 默认圆环颜色
     */
    public static final int CIRCLES_COLOR = Color.GRAY;

    /**
     * 默认字体的粗细程度
     */
    public static final float TEXT_CRUDE = 0;

    /**
     * 默认字体颜色
     */
    public static final int TEXT_COLOR = Color.GRAY;

    /**
     * 默认字体大小
     */
    public static final float TEXT_SIZE = 25;

    /**
     * 默认进度的颜色
     */
    public static final int CURRENT_PROGRESS_COLOR = Color.YELLOW;

    /**
     * 是否显示百分比
     */
    public static final boolean IS_PERCENT = true;

    /**
     * 默认风格
     */
    public static final int STYLE = 1;
}




代码地址:github链接      CSDN下载





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值