文档章节

自定义圆形进度条ProgressBar

遇见sunshine
 遇见sunshine
发布于 2016/01/21 17:39
字数 1162
阅读 54
收藏 0
/**
 * 
 */
package cn.juzhong.view.widget;

import cn.juzhong.R;
import cn.juzhong.util.DensityUtil;
import android.annotation.SuppressLint;
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.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;

/**
 * @author wanggenping
 *
 */
public class RoundProgressBar extends View{
    /**
     * 画笔对象的引用
     */
    private Paint paint;
    
    /**
     * 圆环的颜色
     */
    private int roundColor;
    
    /**
     * 圆环进度的颜色
     */
    private int roundProgressColor;
    
    /**
     * 中间进度百分比的字符串的颜色
     */
    private int textColor;
    
    /**
     * 中间进度百分比的字符串的字体
     */
    private float textSize;
    
    /**
     * 圆环的宽度
     */
    private float roundWidth;
    
    /**
     * 外圆环的宽度
     */
    
    /**
     * 最大进度
     */
    private int max;
    
    /**
     * 当前进度
     */
    private int progress;
    /**
     * 是否显示中间的进度
     */
    private boolean textIsDisplayable;
    
    /**
     * 进度的风格,实心或者空心
     */
    private int style;
    
    public static final int STROKE = 0;
    public static final int FILL = 1;
    
    private Context context;
    
    public RoundProgressBar(Context context) {
        this(context, null);
    }

    public RoundProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    
    public RoundProgressBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.context = context;
        paint = new Paint();
        paint = new Paint();
        paint.setAntiAlias(true); // 消除锯齿
        paint.setStyle(Paint.Style.STROKE); // 绘制空心圆
        
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs,
                R.styleable.RoundProgressBar);
        
        //获取自定义属性和默认值
        roundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor, Color.TRANSPARENT);
        roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.BLUE);
        textColor = mTypedArray.getColor(R.styleable.RoundProgressBar_textColor, Color.GREEN);
        textSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize, 100);
        roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 2);
        
        max = mTypedArray.getInteger(R.styleable.RoundProgressBar_max, 100);
        textIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable, true);
        style = mTypedArray.getInt(R.styleable.RoundProgressBar_style, 0);
        
        mTypedArray.recycle();
    }
    

    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        int center = getWidth()/2;
        int innerCircle = DensityUtil.dip2px(context, 68); //设置内圆半径
        int ringWidth = DensityUtil.dip2px(context, 5); //设置圆环宽度
        
        //绘制内圆
        this.paint.setColor(context.getResources().getColor(R.color.transparent));;
        this.paint.setStrokeWidth(10);//设置内圆的厚度
        canvas.drawCircle(center,center, innerCircle, this.paint);//以该圆为半径向内外扩展至厚度为10px
        
        //绘制圆环,设置圆环的颜色修改画笔的颜色
        this.paint.setColor(context.getResources().getColor(R.color.divider_line_color));
        this.paint.setStrokeWidth(ringWidth);//设置圆环宽度
        canvas.drawCircle(center,center, innerCircle+1+ringWidth/2, this.paint);//圆环宽度为中间圆
        
        //绘制外圆
        this.paint.setColor(context.getResources().getColor(R.color.title_bar_bg_color));
        this.paint.setStrokeWidth(DensityUtil.dip2px(context, 2));
        canvas.drawCircle(center,center, innerCircle+ringWidth, this.paint);
        
        /**
         * 画最外层的大圆环
         */
        int outside = (int) (innerCircle+ringWidth + roundWidth/2);
        paint.setColor(roundColor); //设置圆环的颜色
        paint.setStyle(Paint.Style.STROKE); //设置空心
        paint.setStrokeWidth(roundWidth); //设置圆环的宽度
        paint.setAntiAlias(true);  //消除锯齿 
        canvas.drawCircle(center, center, outside, paint); //画出圆环
        
        /**
         * 画进度百分比
         */
//        paint.setStrokeWidth(0); 
//        paint.setColor(textColor);
//        paint.setTextSize(textSize);
//        paint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体
//        int percent = (int)(((float)progress / (float)max) * 100);  //中间的进度百分比,先转换成float在进行除法运算,不然都为0
//        float textWidth = paint.measureText(percent + "%");   //测量字体宽度,我们需要根据字体的宽度设置在圆环中间
//        
//        if(textIsDisplayable && style == STROKE){
//            canvas.drawText(percent+"", center - textWidth / 2, center + textSize/2, paint); //画出进度百分比
//        }
        
        /**
         * 画圆弧 ,画圆环的进度
         */
        
        //设置进度是实心还是空心
        paint.setStrokeWidth(roundWidth); //设置圆环的宽度
        paint.setColor(roundProgressColor);  //设置进度的颜色
        RectF oval = new RectF(center - outside, center - outside, center
                + outside, center + outside);  //用于定义的圆弧的形状和大小的界限
        
        switch (style) {
        case STROKE:{
            paint.setStyle(Paint.Style.STROKE);
            canvas.drawArc(oval, 0, 360 * progress / max, false, paint);  //根据进度画圆弧
            break;
        }
        case FILL:{
            paint.setStyle(Paint.Style.FILL_AND_STROKE);
            if(progress !=0)
                canvas.drawArc(oval, 0, 360 * progress / max, true, paint);  //根据进度画圆弧
            break;
        }
        }
        
    }
    
    
    public synchronized int getMax() {
        return max;
    }

    /**
     * 设置进度的最大值
     * @param max
     */
    public synchronized void setMax(int max) {
        if(max < 0){
            throw new IllegalArgumentException("max not less than 0");
        }
        this.max = max;
    }

    /**
     * 获取进度.需要同步
     * @return
     */
    public synchronized int getProgress() {
        return progress;
    }

    /**
     * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
     * 刷新界面调用postInvalidate()能在非UI线程刷新
     * @param progress
     */
    public synchronized void setProgress(int progress) {
        if(progress < 0){
            throw new IllegalArgumentException("progress not less than 0");
        }
        if(progress > max){
            progress = max;
        }
        if(progress <= max){
            this.progress = progress;
            postInvalidate();
        }
        
    }
    
    
    public int getCricleColor() {
        return roundColor;
    }

    public void setCricleColor(int cricleColor) {
        this.roundColor = cricleColor;
    }

    public int getCricleProgressColor() {
        return roundProgressColor;
    }

    public void setCricleProgressColor(int cricleProgressColor) {
        this.roundProgressColor = cricleProgressColor;
    }

    public int getTextColor() {
        return textColor;
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
    }

    public float getTextSize() {
        return textSize;
    }

    public void setTextSize(float textSize) {
        this.textSize = textSize;
    }

    public float getRoundWidth() {
        return roundWidth;
    }

    public void setRoundWidth(float roundWidth) {
        this.roundWidth = roundWidth;
    }


}

需要配置自定义view的属性,方便在xml布局中设置。在res/values/attrs

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RoundProgressBar">  
        <attr name="roundColor" format="color"/>
        <attr name="roundProgressColor" format="color"/>
        <attr name="ringColor" format="color"/>
        <attr name="innerCircleColor" format="color"/>
        <attr name="excircleColor" format="color"/>
        <attr name="roundWidth" format="dimension"></attr>
        <attr name="ringWidth" format="dimension"></attr>
        <attr name="innerCircleWidth" format="dimension"></attr>
        <attr name="excircleWidth" format="dimension"></attr>
        <attr name="textColor" format="color" /> 
        <attr name="unitColor" format="color" />  
        <attr name="textSize" format="dimension" /> 
        <attr name="unitSize" format="dimension" /> 
        <attr name="max" format="integer"></attr> 
        <attr name="textIsDisplayable" format="boolean"></attr>
        <attr name="style">
            <enum name="STROKE" value="0"></enum>
            <enum name="FILL" value="1"></enum>
        </attr>
    </declare-styleable> 
    
</resources>

xml布局中

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RoundProgressBar">  
        <attr name="roundColor" format="color"/>
        <attr name="roundProgressColor" format="color"/>
        <attr name="ringColor" format="color"/>
        <attr name="innerCircleColor" format="color"/>
        <attr name="excircleColor" format="color"/>
        <attr name="roundWidth" format="dimension"></attr>
        <attr name="ringWidth" format="dimension"></attr>
        <attr name="innerCircleWidth" format="dimension"></attr>
        <attr name="excircleWidth" format="dimension"></attr>
        <attr name="textColor" format="color" /> 
        <attr name="unitColor" format="color" />  
        <attr name="textSize" format="dimension" /> 
        <attr name="unitSize" format="dimension" /> 
        <attr name="max" format="integer"></attr> 
        <attr name="textIsDisplayable" format="boolean"></attr>
        <attr name="style">
            <enum name="STROKE" value="0"></enum>
            <enum name="FILL" value="1"></enum>
        </attr>
    </declare-styleable> 
    
</resources>

在Java代码中

progressBar.setProgress(borrowInfo.getProgress());


© 著作权归作者所有

遇见sunshine
粉丝 3
博文 55
码字总数 21695
作品 0
海淀
程序员
私信 提问
【详解】Android ProgressBar ProgressDialog 进度条 进度条对话框

多式样ProgressBar 普通圆形ProgressBar 该类型进度条也就是一个表示运转的过程,例如发送短信,连接网络等等,表示一个过程正在执行中。 一般只要在XML布局中定义就可以了。 此时,没有设置...

迷途d书童
2012/02/11
35.5K
2
Android Progressbar

各种类型的Android进度条:CircleProgress: http://www.open-open.com/lib/view/open1415936845930.html#label0 自定义圆形的ProgressBar: http://www.cnblogs.com/xingfuzzhd/archive/2013......

当空皓月
2015/04/20
0
0
一起学Android之ProgressBar

本文简述在Android开发中进度条(ProgressBar)的常见应用,仅供学习分享使用。 概述 在Android开发中,进度条的使用场景有很多,如播放电影时可拖动的观看进度条,评分时使用的评分条,上传下...

Alan.hsiang
01/05
0
0
ProgressBar 进度条

ProgressBar 进度条 在某项延续性工作的进展过程中为了不让用户觉得程序死掉了,需要有个活动的进度条,表示此过程正在进行中。Android中使用ProgressBar来实现这一功能: 1、简单的进度条 ...

鉴客
2011/12/01
1K
0
Android动画之进度条

动画实现自定义圆形加载中效果的进度条 Android开发中在处理耗时工作的时候,例如:列表加载,大多数会有一个精度条加载的框,里面有一个像gif的图片在旋转一样。 定义res/anim/loading.xml:...

切切歆语
2016/11/07
67
0

没有更多内容

加载失败,请刷新页面

加载更多

状态模式

//相当把一个State对象存到Context对象中,然后通过Context实例化对象调用保存的state对象去调用state的相应的方法 https://blog.csdn.net/syc434432458/article/details/51210361...

南桥北木
13分钟前
0
0
基于 Jenkins + JaCoCo 实现功能测试代码覆盖率统计

本文首发于:Jenkins 中文社区 使用 JaCoCo 统计功能测试代码覆盖率? 对于 JaCoCo,有所了解但又不是很熟悉。 "有所了解"指的是在 CI 实践中已经使用 JaCoCo 对单元测试代码覆盖率统计: 当...

Jenkins中文社区
21分钟前
2
0
聊聊Elasticsearch的OsProbe

序 本文主要研究一下Elasticsearch的OsProbe OsProbe elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/monitor/os/OsProbe.java public class OsProbe { private static f......

go4it
21分钟前
0
0
谈谈lucene的DocValues特性之NumericDocValuesField

在默认实现的DocValuesCosumer中,数值有可能分块存储也有可能放在一个数据块中存储。 分块的大小默认是16384,并且通过预先计算如果按一个块存储最大值与最小值的差所占用的比特数和分块存储...

FAT_mt
39分钟前
0
0
【BATJ】面试必问MySQL索引实现原理

BATJ面试题剖析 1、为什么需要使用索引? 2、数据结构Hash、平衡二叉树、B树、B+树区别? 3、机械硬盘、固态硬盘区别? 4、Myisam与Innodb B+树的区别? 5、MySQL中的索引什么数据结构? 6、...

须臾之余
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部