自定义View进度条

public class NumberProgressBar extends View {
    private Context mContext;
    /**
     * 进度
     */
    private int progress;
 
    /**
     * 小圆的半径
     */
    private int smallCircleR;
    /**
     * 大圆的半径
     */
    private int greatCircleR;
    /**
     * 进度条的高度
     */
    private float progressHeight;
    /**
     * 气泡矩形
     */
    private int jR;
 
    /**
     * 未完成进度画笔
     */
    private Paint paintUncheck;
    /**
     * 已经完成的进度画笔
     */
    private Paint paintCheck;
    /**
     * 大圆的画笔
     */
    private Paint paintGreatCircle;
    /**
     * 小圆的画笔
     */
    private Paint paintSmallCircle;
    /**
     * 进度文字画笔
     */
    private Paint paintText;
 
    /**
     * 进度条开始的画笔颜色
     */
    private int starColor = 0xffe5e5e5;
 
    public NumberProgressBar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
 
        paintCheck = new Paint();
        paintUncheck = new Paint();
        paintGreatCircle = new Paint();
        paintSmallCircle = new Paint();
        paintText = new Paint();
 
 
        smallCircleR = dip2px(mContext, 4);
        greatCircleR = dip2px(mContext, 8);
        progressHeight = dip2px(mContext, 10) / 2;
        jR = dip2px(mContext, 6);
 
        initData();
 
    }
 
    /**
     * 初始化数据
     */
    private void initData() {
        //设置未完成进度条的画笔
        paintUncheck.setColor(starColor);
        paintUncheck.setStrokeWidth(dip2px(mContext, 1));
        //抗锯齿
        paintUncheck.setDither(true);
        //防抖动
        paintUncheck.setAntiAlias(true);
        paintUncheck.setStyle(Paint.Style.FILL);
 
        //设置已经完成进度条的画笔
        paintCheck.setColor(Color.parseColor("#0099FF"));
        paintCheck.setStrokeWidth(dip2px(mContext, 1));
        paintCheck.setAntiAlias(true);
        paintCheck.setDither(true);
        paintCheck.setStyle(Paint.Style.FILL);
 
        //大圆画笔
        paintGreatCircle.setColor(Color.parseColor("#0099FF"));
        paintGreatCircle.setAntiAlias(true);
        paintGreatCircle.setStyle(Paint.Style.FILL);
 
        //小圆画笔
        paintSmallCircle.setColor(Color.WHITE);
        paintSmallCircle.setAntiAlias(true);
        paintSmallCircle.setStyle(Paint.Style.FILL);
 
        //设置文字画笔
        paintText.setColor(Color.parseColor("#0099FF"));
        //设置文字的大小
        int paintTextSize = sp2px(mContext, 12);
        paintText.setTextSize(paintTextSize);
        paintText.setAntiAlias(true);
        paintText.setTypeface(Typeface.DEFAULT_BOLD);
 
    }
 
    @SuppressLint("DrawAllocation")
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
 
    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
 
        //得到进度条
        float progressFloat = progress / 100.0f;
        //获得控件的高度
        int viewHeith = getMeasuredHeight();
 
        //jR表示与控件边缘的左右边距,控件的宽度 = 总宽度- 2倍左边距 - 2倍右边距-大圆的半径(为什么要减去大圆,运行就知道了)
        int viewWidth = getMeasuredWidth() - 4 * jR-greatCircleR;
 
        //进度条Y的中心坐标 = 控件的高度 - 大圆的半径
        int viewCenterY = viewHeith - greatCircleR;
 
        //当前进度的移动距离 = 当前的进度比 + 2倍的左边距
        float currentMovedDistance = viewWidth * progressFloat + 2 * jR;
 
        String str = progress + "%";
 
        Rect bounds = new Rect();
        paintText.getTextBounds(str, 0, str.length(), bounds);
        int textWidth = bounds.width();
        int textHeight = bounds.height();
 
        //开始位置为本(文本,距离X的距离,距离Y的位移,画笔对象)
        canvas.drawText(str, currentMovedDistance - textWidth / 2, viewHeith - 2 * greatCircleR -  jR, paintText);
 
 
        //未完成进度的圆角矩形
        canvas.drawRoundRect(new RectF(currentMovedDistance, viewCenterY - progressHeight, viewWidth + 2 * jR, viewCenterY + progressHeight),
                progressHeight, progressHeight, paintUncheck);
 
        //完成进度的圆角矩形
        canvas.drawRoundRect(new RectF(2 * jR, viewCenterY - progressHeight, currentMovedDistance, viewCenterY + progressHeight),
                progressHeight, progressHeight, paintCheck);
 
        RectF greatOval = new RectF(currentMovedDistance - greatCircleR, viewCenterY - greatCircleR, currentMovedDistance + greatCircleR, viewCenterY + greatCircleR);
        RectF smallOval = new RectF(currentMovedDistance - smallCircleR, viewCenterY - smallCircleR, currentMovedDistance + smallCircleR, viewCenterY + smallCircleR);
 
        //大圆
        canvas.drawArc(greatOval, 0, 360, true, paintGreatCircle);
        //小圆
        canvas.drawArc(smallOval, 0, 360, true, paintSmallCircle);
 
    }
 
    /**
     * 设置进度
     *
     * @param progress 传过来的进度
     */
    public void setProgress(int progress) {
        this.progress = progress;
        invalidate();
    }
 
    public int dip2px(Context ctx, float dp) {
        float density = ctx.getResources().getDisplayMetrics().density;
        int px = (int) (dp * density + 0.5f);
        return px;
    }
 
    public int sp2px(Context context, float spValue) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spValue, context.getResources().getDisplayMetrics());
    }
}

使用方法:现在xml中引用

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:background="@drawable/update_app_bg"
    android:minHeight="190dp"
    android:minWidth="260dp">
 
    <com.csc.widget.NumberProgressBar
        android:id="@+id/number_progress"
        android:layout_width="260dp"
        android:layout_height="150dp"/>
 
</android.support.constraint.ConstraintLayout>

然后再代码中设置:

private int mProgress;
private NumberProgressBar mNumberProgressBar;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mNumberProgressBar = findViewById(R.id.number_progress);                                       
         updateProgress();
 
}
 
private void updateProgress() {
        try {
            mProgress++;
            Message msg = handler.obtainMessage();
            msg.what = 100;
            msg.obj = mProgress;
            handler.sendMessage(msg);
 
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
 @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int progress = (int) msg.obj;
            mNumberProgressBar.setProgress(progress);
            if (progress <100) {
                
               updateProgress();
            }
        }
    };
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、概述   Long Long Ago,由于当时技术有限,使用一些第三方库才能勉强能够实现这个效果,但是还是存在...
    aositeluoke阅读 331评论 0 0
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,171评论 1 32
  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,855评论 0 4
  • 【读经】 代下35章 【金句】 歌唱的亚萨之子孙,照着大卫、亚萨、希幔,和王的先见耶杜顿所吩咐的,站在自己的地位上...
    chanor阅读 3,156评论 0 0
  • 高艳峰 信阳 网络初级九期 坚持原创分享第39天 2018-05-08 尊敬的~老师您好!自孩子进入~班,...
    gyf16阅读 311评论 0 0