使用



public class MainActivity extends Activity implements OnComompleteListener {
    private int num = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_progressbar);
        CustomProgressBar pb1 = (CustomProgressBar) findViewById(R.id.pb1);
        CustomProgressBar pb2 = (CustomProgressBar) findViewById(R.id.pb2);
        CustomProgressBar progressBar = new CustomProgressBar(this);
        ((LinearLayout) findViewById(R.id.root)).addView(progressBar);
        pb1.setToNext(true);
        pb2.setToNext(false);
        progressBar.setToNext(false);
        pb1.setOnComompleteListener(this);
        pb2.setOnComompleteListener(this);
        progressBar.setOnComompleteListener(this);
    }
    @Override
    public void onComplete(CustomProgressBar pb, boolean isToNext) {
        switch (pb.getId()) {
        case R.id.pb1:
            Toast.makeText(this, pb.getId() + "-跑完了,是否继续跑-" + isToNext, Toast.LENGTH_SHORT).show();
            num++;
            if (num > 1) pb.setToNext(false);
            break;
        default:
            Toast.makeText(this, pb.getId() + "-跑完了,是否继续跑-" + isToNext, Toast.LENGTH_SHORT).show();
            break;
        }
    }
}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bqt="http://schemas.android.com/apk/res/com.bqt.myview"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:padding="5dp" >
    <com.bqt.myview.CustomProgressBar
        android:id="@+id/pb1"
        android:layout_width="80dp"
        android:layout_height="80dp"
        bqt:circleWidth="5dp"
        bqt:firstColor="#D4F668"
        bqt:secondColor="#2F9DD2"
        bqt:speed="20" />
    <com.bqt.myview.CustomProgressBar
        android:id="@+id/pb2"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        bqt:circleWidth="30dp"
        bqt:firstColor="#16A3FA"
        bqt:secondColor="#D20F02"
        bqt:speed="10" />
</LinearLayout>

View

public class CustomProgressBar extends View {
    /**第一圈的颜色*/
    private int mFirstColor = Color.GREEN;
    /**第二圈的颜色*/
    private int mSecondColor = Color.RED;
    /**圈的宽度*/
    private int mCircleWidth = 40;
    /**当前进度*/
    private int mProgress = 0;
    /**速度。实际代表的是休眠时间,这里只是为了方便演示*/
    private int mSpeed = 30;
    /**进度的百分比形式*/
    private String percent = "0%";
    /**绘制时文本绘制的范围*/
    private Rect mRect = null;
    /**绘制时文本的大小*/
    private int sTextSize = 40;
    /**绘制时文本的颜色*/
    private int sTextColor = Color.BLACK;
    /**画笔*/
    private Paint mPaint = null;
    /**是否应该开始下一个*/
    private boolean isToNext = false;
    /**用于定义圆弧的形状和大小的界限*/
    private RectF oval;
    private OnComompleteListener mListener;

    public CustomProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public CustomProgressBar(Context context) {
        this(context, null);
    }
    public CustomProgressBar(final Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mRect = new Rect();
        mPaint = new Paint();
        oval = new RectF();
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomProgressBar, defStyle, 0);
        for (int i = 0; i < typedArray.getIndexCount(); i++) {
            int attr = typedArray.getIndex(i);
            switch (attr) {
            case R.styleable.CustomProgressBar_firstColor:
                mFirstColor = typedArray.getColor(attr, Color.GREEN);
                break;
            case R.styleable.CustomProgressBar_secondColor:
                mSecondColor = typedArray.getColor(attr, Color.RED);
                break;
            case R.styleable.CustomProgressBar_circleWidth:
                mCircleWidth = typedArray.getDimensionPixelSize(attr,
                        (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics()));
                break;
            case R.styleable.CustomProgressBar_speed:
                mSpeed = typedArray.getInt(attr, 20);
                break;
            }
        }
        typedArray.recycle();

        // 绘图线程
        new Thread() {
            public void run() {
                while (true) {
                    mProgress++;
                    if (mProgress == 360) {
                        if (mListener != null && context instanceof Activity) {
                            ((Activity) context).runOnUiThread(new Runnable() {//Activity拿到回调时,不能直接在子线程中更新UI
                                        @Override
                                        public void run() {
                                            mListener.onComplete(CustomProgressBar.this, isToNext);
                                        }
                                    });
                        }
                        mProgress = 0;
                        percent = "100%";
                        if (!isToNext) {//如果不继续转的话就停止
                            mPaint.getTextBounds(percent, 0, percent.length(), mRect);
                            postInvalidate();//要刷新一下,否则最后的状态可能没绘制上
                            return;
                        }
                    } else if (mProgress % 10 == 0) {//每10个进度刷新一次,目的是防止频繁的更新进度。实际项目中不需要考虑!
                        percent = mProgress * 100 / 360 + "%";
                    }
                    mPaint.getTextBounds(percent, 0, percent.length(), mRect);//将初始文本的边界值封装到矩形mRect中
                    postInvalidate();
                    try {
                        Thread.sleep(mSpeed);
                    } catch (InterruptedException e) {
                    }
                }
            };
        }.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mPaint.setAntiAlias(true); // 消除锯齿
        mPaint.setStyle(Paint.Style.STROKE); //空心
        mPaint.setStrokeWidth(mCircleWidth); // 设置圆环的宽度
        int centre = getWidth() / 2; // 获取圆心的x坐标
        int radius = centre - mCircleWidth / 2;// 半径
        oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius); // 用于定义的圆弧的形状和大小的界限
        if (!isToNext) {// 第一颜色的圈完整,第二颜色跑
            mPaint.setColor(mFirstColor); // 设置圆环的颜色
            canvas.drawCircle(centre, centre, radius, mPaint); // 画出圆环
            mPaint.setColor(mSecondColor); // 设置圆环的颜色
            canvas.drawArc(oval, -90, mProgress, false, mPaint); // 根据进度画圆弧
        } else {
            mPaint.setColor(mSecondColor); // 设置圆环的颜色
            canvas.drawCircle(centre, centre, radius, mPaint); // 画出圆环
            mPaint.setColor(mFirstColor); // 设置圆环的颜色
            canvas.drawArc(oval, -90, mProgress, false, mPaint); // 根据进度画圆弧
        }
        //再绘制一个知识当前进度的文字,先包装文字的范围,再根据此大小调整文字的位置
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setTextSize(sTextSize);
        mPaint.setColor(sTextColor);
        canvas.drawText(percent, centre - mRect.width() / 2, centre + mRect.height() / 2, mPaint);
    }

    public boolean isToNext() {
        return isToNext;
    }
    public void setToNext(boolean isToNext) {
        this.isToNext = isToNext;
    }

    //自定义的回调
    public interface OnComompleteListener {
        public void onComplete(CustomProgressBar pb, boolean isToNext);
    }
    public void setOnComompleteListener(OnComompleteListener listener) {
        mListener = listener;
    }
}

自定义属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 定义在外面的好处是:其他自定义控件也可以使用这些属性 -->
    <attr name="firstColor" format="color" />
    <attr name="secondColor" format="color" />
    <attr name="circleWidth" format="dimension" />
    <attr name="speed" format="integer" />
    <declare-styleable name="CustomProgressBar">
        <attr name="firstColor" />
        <attr name="secondColor" />
        <attr name="circleWidth" />
        <attr name="speed" />
    </declare-styleable>
</resources>

自定义控件 环形进度条 ProgressBar的更多相关文章

  1. 进度条ProgressBar

    在本节中,作者只写出了进度条的各种样式,包括圆形.条形,还有自定义的条形,我想如果能让条形进度条走满后再继续从零开始,于是我加入了一个条件语句.作者的代码中需要学习的是handler在主线程和子线程中 ...

  2. Android简易实战教程--第十七话《自定义彩色环形进度条》

    转载请注明出处:http://blog.csdn.net/qq_32059827/article/details/52203533   点击打开链接 在Android初级教程里面,介绍了shape用法 ...

  3. Android零基础入门第51节:进度条ProgressBar

    原文:Android零基础入门第51节:进度条ProgressBar 不知不觉这已经是第51期了,在前面50期我们学了Android开发中使用频率非常高的一些UI组件,当然这些组件还不足够完成所有AP ...

  4. 图解CSS3制作圆环形进度条的实例教程

    圆环形进度条制作的基本思想还是画出基本的弧线图形,然后CSS3中我们可以控制其旋转来串联基本图形,制造出部分消失的效果,下面就来带大家学习图解CSS3制作圆环形进度条的实例教程 首先,当有人说你能不能 ...

  5. iOS带动画的环形进度条(进度条和数字同步)

    本篇写的是实现环形进度条,并带动画效果,要实现这些,仅能通过自己画一个 方法直接看代码 为了方便多次调用,用继承UIView的方式 .m文件 #import <UIKit/UIKit.h> ...

  6. iOS 开发技巧-制作环形进度条

    有几篇博客写到了怎么实现环形进度条,大多是使用Core Graph来实现,实现比较麻烦且效率略低,只是一个小小的进度条而已,我们当然是用最简单而且效率高的方式来实现. 先看一下这篇博客,博客地址:ht ...

  7. iOS一分钟学会环形进度条

    有几篇博客写到了怎么实现环形进度条,大多是使用Core Graph来实现,实现比较麻烦且效率略低,只是一个小小的进度条而已,我们当然是用最简单而且效率高的方式来实现.先看一下这篇博客,博客地址:htt ...

  8. Android 自学之进度条ProgressBar

    进度条(ProgressBar)也是UI界面中的一种非常使用的组件,通常用于向用户显示某个耗时完成的百分比.因此进度条可以动态的显示进度,因此避免长时间地执行某个耗时操作时,让用户感觉程序失去了响应, ...

  9. WPF的进度条progressbar,运行时间elapse time和等待spinner的实现

    今天用.NET 4.5中的TPL的特性做了个小例子,实现了WPF的进度条progressbar,运行时间elapse time和等待spinner. 先上图吧.   这个例子包含4个实现,分别是同步版 ...

随机推荐

  1. 重新认识Swift中的可选型(Swift2.1)

    //: Playground - noun: a place where people can play import UIKit /* Swift中nil代表是是另外一种类型, 而不像OC那样, 任 ...

  2. 武汉科技大学ACM:1002: 华科版C语言程序设计教程(第二版)例题6.6

    Problem Description 明天就要英语考试了,小明明正在挑灯夜 战背单词.小明明发现单词很难背,背一个忘一个.经过仔细研究,小明明发现单词难背的原因是因为某个字符的出现,破坏了整个单词的 ...

  3. php的冒泡算法

    <?php /* 冒泡算法  * @para $arr 传人进去排序的数组  * @return $newArr 排序之后的数组  */   function maopao($arr){     ...

  4. UBUNTU 下设置全局 path变量

    全局的对所有用户都可以的使用的PATH: 可以通过修改配置文件: /etc/bashrc 和 /etc/profile 来时配置, 全局的PATH; 例如: vi /etc/profile 在最后后加 ...

  5. delphi2010 开发及调试WebService 实例

    使用delphi已经10多年了,一直搞桌面程序开发,对Webservice一直很陌生,近来因工作需要,学习delphi开发WebService,担心遗忘,作此笔记. 特别感谢 中塑在线技术总监 大犇 ...

  6. linux下实现ls()函数遍历目录

    转载请注明原创:http://www.cnblogs.com/StartoverX/p/4600794.html 需求:在linux下遍历目录,输出目录中各文件名. 在linux下遍历目录的相关函数有 ...

  7. FSG1.33解压缩算法分析

    之前只是知道怎样脱去fsg壳,对壳的压缩算法没有太多的注意,今天就对算法进行一些分析 使用的版本是fsg1.33,首先用peid查壳: 2.将程序载入OD,看到如下代码 可以看到这段代码主要是从以es ...

  8. 大整数算法[11] Karatsuba乘法

    ★ 引子         前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...

  9. iOS开发之UIWebView自动滑动到顶部-备

    但可以通过subview来操作. 通常用UIWebView加载网页,有时候需要点击一个按钮,或者页面的某个部位,使页面自动滚动到顶部,但是UIWebView不像UIScrollView那么方便.   ...

  10. ural 1613 For Fans of Statistics

    #include <cstdio> #include <cstring> #include <map> #include <vector> #inclu ...