使用



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. AFNetworking 3.0的GET和POST的使用

    POST: AFHTTPSessionManager *session = [AFHTTPSessionManager manager]; session.requestSerializer = [A ...

  2. 详解CSS选择器、优先级与匹配原理

    原文链接:http://polaris1119.javaeye.com/blog/764428 作为一个Web开发者,掌握必要的前台技术也是很重要的,特别是在遇到一些实际问题的时候.这里给大家列举一个 ...

  3. MySQL如何执行关联查询

    MySQL中‘关联(join)’ 一词包含的意义比一般意义上理解的要更广泛.总的来说,MySQL认为任何一个查询都是一次‘关联’ --并不仅仅是一个查询需要到两个表的匹配才叫关联,索引在MySQL中, ...

  4. deb文件安装命令

    一般在此类发行版中可以直接双击安装 手动安装.如果您喜欢使用终端,您需要管理员权限来安装一个 .deb 文件. 打开终端后,输入: sudo dpkg -i package_file.deb 要卸载一 ...

  5. linux打包/解压-tar

    tar命令: 压缩: tar -zcvf  打包的文件名.tar.gz 打包的文件 解压: tar -zxvf  要压缩的文件名.tar.gz

  6. MetaData元数据

    一.基础 定义:数据库.表.列相关信息的描述.    何时使用:想取得对数据库的信息时使用.    一]数据库元数据——通过DataBaseMetaData            DataBaseMe ...

  7. 8.2.1.7 Use of Index Extensions 使用索引扩展

    8.2.1.7 Use of Index Extensions 使用索引扩展 InnoDB 自动扩展每个secondary index 通过添加primary key columns to it,考虑 ...

  8. 【转】BT5无法找到软件安装包(提供可用的BT更新源)

    像我这种一般想起才玩玩BT5的人,跟不上讯息的变化. 偶尔想尝试某个实验,然后去安装,发现提示无法找到软件安装包. 这个时候,应该注意到,现在已经从BT5到kali了,假如想我这种人,肯定比较少留意软 ...

  9. Android软件的国际化

    软件的国际化指的就是:在不同语言的环境的操作系统下,显示不同的语言 2 其实实现软件的国际化很简单: 3 4 1.如果是对文字的国际化,只需要在res文件夹下面建立如下文件夹: 5 values-zh ...

  10. MSSQL 生成有意义的PROC

    MSSQL 生成有意义的PROC --MSSQL  用PROC 生成有意义的单号:如WP200011101 GO/****** 对象:  Table [dbo].[tbl_SequenceNum]   ...