自定义圆形ProgressBar

<span style="font-family: Arial, Helvetica, sans-serif;">一、在attrs.xml中定义</span>

<declare-styleable name="RoundProgressBar">
        <attr name="roundColor" format="color" />
        <attr name="roundProgressColor" format="color" />
        <attr name="roundWidth" format="dimension"></attr>
        <attr name="textColor" format="color" />
        <attr name="textSize" 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>

二、自定义视图

/**
 * 自定义圆形进度条
 * 
 * @author Macro_Xiao
 * 
 */
@SuppressLint("HandlerLeak")
public class CircleProgressBar 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 int perProgress;

	public CircleProgressBar(Context context) {
		this(context, null);
	}

	public CircleProgressBar(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public CircleProgressBar(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		paint = new Paint();

		TypedArray mTypedArray = context.obtainStyledAttributes(attrs,
				R.styleable.RoundProgressBar);

		// 获取自定义属性和默认值
		roundColor = mTypedArray.getColor(
				R.styleable.RoundProgressBar_roundColor, Color.RED);
		roundProgressColor = mTypedArray.getColor(
				R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN);
		textColor = mTypedArray.getColor(
				R.styleable.RoundProgressBar_textColor, Color.GREEN);
		textSize = mTypedArray.getDimension(
				R.styleable.RoundProgressBar_textSize, 15);
		roundWidth = mTypedArray.getDimension(
				R.styleable.RoundProgressBar_roundWidth, 5);
		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 centre = getWidth() / 2; // 获取圆心的x坐标
		int radius = (int) (centre - roundWidth / 2); // 圆环的半径
		paint.setColor(roundColor); // 设置圆环的颜色
		paint.setStyle(Paint.Style.STROKE); // 设置空心
		paint.setStrokeWidth(roundWidth); // 设置圆环的宽度
		paint.setAntiAlias(true); // 消除锯齿
		canvas.drawCircle(centre, centre, radius, paint); // 画出圆环
		/** 画进度百分比 */
		paint.setStrokeWidth(0);
		paint.setColor(textColor);
		paint.setTextSize(getResources().getDimension(R.dimen.progress_text));
		paint.setTypeface(Typeface.DEFAULT_BOLD); // 设置字体
		int percent = (int) (((float) countProgress / (float) max) * 100); // 中间的进度百分比,先转换成float在进行除法运算,不然都为0
		float numWidth = paint.measureText(percent + ""); // 测量字体宽度,我们需要根据字体的宽度设置在圆环中间

		if (textIsDisplayable && percent != 0 && style == STROKE) {
			canvas.drawText(percent + "", centre - (numWidth + 40) / 2, centre
					+ textSize / 2, paint); // 画出进度百分比值
		}
		// 绘制"%"
		paint.setTextSize(getResources().getDimension(R.dimen.left_tv_size));
		canvas.drawText("%", centre + (numWidth - 25) / 2, centre
				+ (textSize - 50) / 2, paint);
		// 绘制"已用"
		canvas.drawText(getResources().getString(R.string.used_memory), centre
				+ (numWidth - 25) / 2, centre + (textSize) / 2, paint);
		/** 画圆弧 ,画圆环的进度 */
		// 设置进度是实心还是空心
		paint.setStrokeWidth(roundWidth); // 设置圆环的宽度
		if (percent <= 50) {
			paint.setColor(getResources()
					.getColor(R.color.progress_color_green));
		} else if (percent > 50 && percent < 80) {
			paint.setColor(getResources().getColor(
					R.color.progress_color_yellow));
		} else if (percent >= 80) {
			paint.setColor(getResources().getColor(R.color.progress_color_red));
		}
		RectF oval = new RectF(centre - radius, centre - radius, centre
				+ radius, centre + radius); // 用于定义的圆弧的形状和大小的界限
		switch (style) {
		case STROKE: {
			paint.setStyle(Paint.Style.STROKE);
			canvas.drawArc(oval, 270, 360 * countProgress / max, false, paint); // 根据进度画圆弧
			break;
		}
		case FILL: {
			paint.setStyle(Paint.Style.FILL_AND_STROKE);
			if (countProgress != 0)
				canvas.drawArc(oval, 270, 360 * countProgress / 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;
			this.perProgress = progress / 10;
			countProgress = perProgress;
			handler.sendEmptyMessage(0);
		}
	}
	private int countProgress = 0;
	private Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			postInvalidate();
			if (countProgress < progress) {
				countProgress+=perProgress;
				handler.sendEmptyMessageDelayed(0, 100);
			}
		}

	};

	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;
	}
}

三、布局中使用

    <FrameLayout
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_gravity="center"
        android:layout_marginBottom="30dp" >

        <ImageView
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:src="@drawable/progress_bg" />

        <carnetos.manageapps.view.CircleProgressBar
            android:id="@+id/memory_progress"
            android:layout_width="150dp"
            android:layout_height="150dp"
            carnetos:roundColor="@android:color/transparent"
            carnetos:roundProgressColor="@color/progress_color_green"
            carnetos:roundWidth="7dp"
            carnetos:textColor="@drawable/white"
            carnetos:textSize="30dp" />
    </FrameLayout>



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值