自定义->圆形进度条

接着上一篇开始更新
圆形进度条,需要要有一个圆作为 布景,一个圆弧来展示进度
这里写图片描述
1. 先进行自定义属性的设置

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="progress">
        <attr name="circle_width" format="dimension" />
        <attr name="circle_color" format="color" />
        <attr name="progress_width" format="dimension" />
        <attr name="progress_color" format="color" />
        <attr name="progress" format="float" />
    </declare-styleable>

</resources>
  1. 自定义View的整段代码
package com.circle.progress;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
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.Paint.FontMetrics;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.LinearInterpolator;

@SuppressLint("NewApi")
public class ProgressCircle extends View implements AnimatorUpdateListener{

    private float circle_width; // 圆的宽度
    private int circle_color; // 圆的颜色
    private float progress_width; // 进度条的宽度
    private int progress_color; // 进度条的颜色
    private int centerX; // 圆心的X坐标
    private int centerY; // 圆心的Y坐标
    private int max = 100; // 总进度

    private float mProgress; // 当前进度

    private Paint circle_Paint;
    private Paint progress_Paint;
    private Paint mTextPaint;
    private int radius;

    public ProgressCircle(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray mTd = context.obtainStyledAttributes(attrs,
                R.styleable.progress);
        circle_width = mTd.getDimension(R.styleable.progress_circle_width, 5);
        circle_color = mTd.getColor(R.styleable.progress_circle_color,Color.GRAY);
        progress_width = mTd.getDimension(R.styleable.progress_progress_width,5);
        progress_color = mTd.getColor(R.styleable.progress_progress_color,Color.GRAY);
        mProgress = mTd.getFloat(R.styleable.progress_progress, 0);
        mTd.recycle();
        initPaint();
    }

    private void initPaint() {
        circle_Paint = new Paint();
        circle_Paint.setColor(circle_color); // 圆颜色
        circle_Paint.setStyle(Paint.Style.STROKE); // 是否空心
        circle_Paint.setAntiAlias(true); // 抗锯齿
        circle_Paint.setStrokeWidth(circle_width); // 圆的宽度

        progress_Paint = new Paint();
        progress_Paint.setColor(progress_color);
        progress_Paint.setStyle(Paint.Style.STROKE);
        progress_Paint.setAntiAlias(true);
        progress_Paint.setStrokeWidth(progress_width);

        mTextPaint = new Paint();
        /*
         * 画出中间文字进度百分比
         */
        mTextPaint.setStrokeWidth(0);
        mTextPaint.setColor(Color.BLACK);
        mTextPaint.setTextSize(80);
        mTextPaint.setTypeface(Typeface.DEFAULT_BOLD); // 设置字体
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        centerX = getWidth() / 2;   //圆心的x坐标
        centerY = getHeight() / 2;
        radius = (int) (centerX - circle_width / 2);    //半径
        canvas.drawCircle(centerX, centerY, radius, circle_Paint);


        int percent = (int) (((float) mProgress / (float) max) * 100); // 中间的进度百分比,先转换成float在进行除法运算,不然都为0
        float textWidth = mTextPaint.measureText(percent + "%"); // 测量字体宽度,我们需要根据字体的宽度设置在圆环中间
        canvas.drawText(percent + "%", centerX - textWidth / 2,
                centerY + textWidth /6, mTextPaint); // 画出进度百分比

        RectF oval = new RectF(); // 圆弧要根据矩形来画
        // 矩形的四点坐标
        oval.left = (centerX - radius);
        oval.top = (centerY - radius);
        oval.right =(centerX + radius);
        oval.bottom = (centerY + radius);
        if (mProgress > 0) {
            canvas.drawArc(oval, -90, 360*mProgress/max, false,
                    progress_Paint);
        }
    }

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

    /**
     * 设置进度,考虑到线程安全
     * 
     * @param progress
     */
    @SuppressLint("NewApi")
    public synchronized void setProgress(float progress) {
        if (progress > max) {
            this.mProgress = max;
        }
        if (progress <= max) {
            this.mProgress = progress;
            postInvalidate();
        }
    }
     /**
      * 
      * 动画的形式来展示进度条
      */
    public synchronized void anim(float progress) {
        //得到当前自定义View的属性动画
        final ObjectAnimator animator = ObjectAnimator.ofFloat(this, "progress", 0f, progress);
        animator.setDuration(1000);
        animator.addUpdateListener(this);
        animator.setInterpolator(new LinearInterpolator());
        postDelayed(new Runnable() {
            @Override
            public void run() {
                animator.start();
            }
        }, 350);
    }

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        invalidate();
    }

}
  1. 在xml里进行设置
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <com.circle.progress.ProgressCircle
        android:id="@+id/cirle"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        app:circle_color="#cccccc"
        app:progress = "0"
        app:circle_width="5dp"
        app:progress_color="#ff0000"
        app:progress_width="5dp" />

</RelativeLayout>
  1. 在Activity中进行调用
private void initView() {
        prg = (ProgressCircle) findViewById(R.id.cirle);
        prg.anim(80);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值