Android 圆形进度条

这里写图片描述

  • 目录结构
    这里写图片描述

  • 核心代码CicleProgressView.java

public class CircleProgressView extends View {

    /**
     * 背景颜色
     */
    private int backgroundColor;
    /**
     * 前景颜色
     */
    private int foregroundColor;
    /**
     * 进度条颜色
     */
    private int progressColor;
    /**
     * 字体颜色
     */
    private int fontColor;
    /**
     * 当前进度
     */
    private int currentProgress = 0;
    /**
     * 最大进度
     */
    private int maxProgress;
    /**
     * 画笔
     */
    private Paint mPaint = new Paint();
    /**
     * 半径长
     */
    private int mRadius;
    /**
     * 进度宽
     */
    private int progressWidth;
    /**
     * 字体大小
     */
    private int textSize;
    /**
     * 回调监听
     */
    private ProgressedListener listener;

    public CircleProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView);
        backgroundColor = a.getColor(R.styleable.CircleProgressView_circleprogress_backgroundcolor, Color.WHITE);
        foregroundColor = a.getColor(R.styleable.CircleProgressView_circleprogress_foregroundcolor, Color.WHITE);
        progressColor = a.getColor(R.styleable.CircleProgressView_circleprogress_progresscolor, Color.BLUE);
        fontColor = a.getColor(R.styleable.CircleProgressView_circleprogress_fontcolor, Color.BLUE);
        maxProgress = a.getInteger(R.styleable.CircleProgressView_circleprogress_maxprogress, 100);
        progressWidth = a.getInteger(R.styleable.CircleProgressView_circleprogress_width, 10);
        textSize = a.getInteger(R.styleable.CircleProgressView_circleprogress_textsize, 10);
        a.recycle();//释放资源
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
//        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
//        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200, 200);
        } else if (widthSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(heightMeasureSpec, heightMeasureSpec);
        } else if (heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthMeasureSpec, widthMeasureSpec);
        }

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (w > h) {
            mRadius = h / 2;
        } else {
            mRadius = w / 2;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(backgroundColor);
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, mRadius, mPaint);//画最下边的圆
        mPaint.setColor(progressColor);
        canvas.drawArc(getWidth() / 2 - mRadius,
                getHeight() / 2 - mRadius,
                getWidth() / 2 + mRadius,
                getHeight() / 2 + mRadius,
                -90,
                360 * (((float) currentProgress) / maxProgress),
                true,
                mPaint);//画扇形
        mPaint.setColor(foregroundColor);
        canvas.drawCircle(getWidth() / 2, getHeight() / 2,
                mRadius - TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, progressWidth, getResources().getDisplayMetrics()),
                mPaint);//画中心圆
        mPaint.setColor(fontColor);
        mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, textSize, getResources().getDisplayMetrics()));
        String text = currentProgress + "%";
        canvas.drawText(text,
                getWidth() / 2 - mPaint.measureText(text) / 2,
                getHeight() / 2 + mPaint.measureText("%") / 2,
                mPaint);//画文字
    }

    /**
     * 设置当前进度
     *
     * @param currentProgress
     */
    public void setCurrentProgress(int currentProgress) {
        if (currentProgress <= 0) {
            currentProgress = 0;
            if (listener != null) {
                listener.startLoad();
            }
        }
        if (currentProgress >= maxProgress) {
            currentProgress = maxProgress;
            if (listener != null) {
                listener.loadEnd();
            }
        }
        this.currentProgress = currentProgress;
        if (listener != null) {
            listener.progressLoading(currentProgress);
        }
        invalidate();//重绘
    }

    public void setListener(ProgressedListener listener) {
        this.listener = listener;
    }

    public interface ProgressedListener {
        void loadEnd();//加载结束

        void progressLoading(int progressed);//加载中

        void startLoad();//开始加载
    }
}

  • 自定义属性 attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CircleProgressView">
        <!-- 背景色-->
        <attr name="circleprogress_backgroundcolor" format="color" />
        <!-- 前景色-->
        <attr name="circleprogress_foregroundcolor" format="color" />
        <!-- 进度条颜色 -->
        <attr name="circleprogress_progresscolor" format="color" />
        <!-- 字体颜色-->
        <attr name="circleprogress_fontcolor" format="color" />
        <!-- 最大进度 -->
        <attr name="circleprogress_maxprogress" format="integer" />
        <!-- 进度宽 -->
        <attr name="circleprogress_width" format="integer" />
        <!-- 字体大小-->
        <attr name="circleprogress_textsize" format="integer" />

    </declare-styleable>
</resources>
  • 布局文件 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:circleprogress="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.wxq.me.mycsdndemo.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <com.wxq.me.mycsdndemo.CircleProgressView
            android:id="@+id/circle_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            circleprogress:circleprogress_backgroundcolor="#dddddd"
            circleprogress:circleprogress_fontcolor="#0000ff"
            circleprogress:circleprogress_foregroundcolor="#ffffff"
            circleprogress:circleprogress_maxprogress="100"
            circleprogress:circleprogress_progresscolor="#0000ff" />

        <com.wxq.me.mycsdndemo.CircleProgressView
            android:id="@+id/circle_view1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            circleprogress:circleprogress_backgroundcolor="#000000"
            circleprogress:circleprogress_fontcolor="#ff0000"
            circleprogress:circleprogress_foregroundcolor="#ffffff"
            circleprogress:circleprogress_maxprogress="100"
            circleprogress:circleprogress_progresscolor="#ff0000"
            circleprogress:circleprogress_textsize="20"
            circleprogress:circleprogress_width="5" />

        <com.wxq.me.mycsdndemo.CircleProgressView
            android:id="@+id/circle_view2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            circleprogress:circleprogress_backgroundcolor="#ff0000"
            circleprogress:circleprogress_fontcolor="#ffff00"
            circleprogress:circleprogress_foregroundcolor="#ffffff"
            circleprogress:circleprogress_maxprogress="100"
            circleprogress:circleprogress_progresscolor="#ffff00"
            circleprogress:circleprogress_textsize="20"
            circleprogress:circleprogress_width="5" />
    </LinearLayout>

    <com.wxq.me.mycsdndemo.CircleProgressView
        android:id="@+id/circle_view3"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        circleprogress:circleprogress_backgroundcolor="#dddddd"
        circleprogress:circleprogress_fontcolor="#00ffff"
        circleprogress:circleprogress_foregroundcolor="#ffffff"
        circleprogress:circleprogress_maxprogress="100"
        circleprogress:circleprogress_progresscolor="#00ffff"
        circleprogress:circleprogress_textsize="50"
        circleprogress:circleprogress_width="20" />
</LinearLayout>

  • MainActivity.java
public class MainActivity extends AppCompatActivity {

    private CircleProgressView mCircleProgressView, mCircleProgressView1, mCircleProgressView2, mCircleProgressView3;

    private int currentProgress = 0;

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if (currentProgress <= 100) {
                mCircleProgressView.setCurrentProgress(currentProgress);
                mCircleProgressView1.setCurrentProgress(currentProgress);
                mCircleProgressView2.setCurrentProgress(currentProgress);
                mCircleProgressView3.setCurrentProgress(currentProgress);
                Log.i("wx", currentProgress + "");
                currentProgress++;
                sendEmptyMessageDelayed(1, 10);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mCircleProgressView = (CircleProgressView) findViewById(R.id.circle_view);
        mCircleProgressView1 = (CircleProgressView) findViewById(R.id.circle_view1);
        mCircleProgressView2 = (CircleProgressView) findViewById(R.id.circle_view2);
        mCircleProgressView3 = (CircleProgressView) findViewById(R.id.circle_view3);
        mCircleProgressView.setListener(new CircleProgressView.ProgressedListener() {
            @Override
            public void loadEnd() {
                Toast.makeText(MainActivity.this, "加载结束", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void progressLoading(int progressed) {
                //TODO
            }

            @Override
            public void startLoad() {
                Toast.makeText(MainActivity.this, "加载开始", Toast.LENGTH_SHORT).show();
            }
        });
        mHandler.sendEmptyMessageDelayed(1, 1000);
    }
}

  • 实现思路

    1. 在onDraw方法中先中绘制外圆,再去绘制扇形,再绘制内圆,最后绘制文字。
    2. 在CircleProgressView定义接口ProgressedListener,MainActivity中实现这个接口,开始加载回调startLoad方法,加载中回调progressLoading方法,加载结束回调loadEnd方法。
    3. 在MainActivity使用handler模拟进度加载调用setCurrentProgress方法。
  • 下载地址
    http://download.csdn.net/detail/zhe_ge_sha_shou/9650195

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值