Android 自定义绘制圆形进度条(扩展性强!)

来源:互联网 发布:滴答清单 windows 编辑:程序博客网 时间:2024/05/17 21:48

    这几天在做电池管家的一个项目,有许多的地方需要用到这个圆形进度条,而且还要根据不同的状态去切换样式,比如手机是否在充电。充电的情况下圆形进度条中间就要显示一个充电的图标,不充电的情况下就显示电量的百分比等内容。因此花了点时间写了一个比较不错的demo,这个demo的扩展性比较强,而且也比较灵活。废话就不多说了!我先上几张图给大家看看,然后再贴上源码,好东西就是要分享,欢迎大家学习使用。




OK,上面三个图中,想必大家一看也都清楚了,分别有三种状态可以选择。大家也可以根据自己样式去修改。下面我将贴出源码。

RoundProgressBar.java

package com.qiulong.roundprogressbar;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.Path;import android.graphics.RectF;import android.graphics.Paint.Style;import android.util.AttributeSet;import android.view.View;import com.qiulong.circlepregress.R;/** * 自定义环形进度条 * @author qiulong * */@SuppressLint("DrawAllocation")public class RoundProgressBar extends View {/** 默认圆环的画笔 */private Paint defaultRoundPaint;/** 圆环进度的画笔 */private Paint progresRoundPaint;/** 百分比字体的画笔 */private Paint percenTextPaint;/** 电量字体的画笔 */private Paint electriTextPaint;/** 默认圆环的背景颜色 */private int defaultRoundColor;/** 圆环进度的颜色 */private int roundProgressColor;/** 百分比字体颜色 */private int percenTextColor;/** 电量字体颜色 */private int electriTextColor;/** 百分比字体大小 */private float percenTextSize;/** 电量字体大小 */private float electriTextSize;/** 电量文字内容*/private String electriText;/** 是否显示电量文字(默认是不显示)*/private boolean showElectriText = false;/** 圆环进度的宽度 */private float roundWidth;/** 圆环进度的最大值,默认100 */private int max;/** 当前进度值 */private int progress;/** 圆弧的外轮廓矩形区域 */private RectF oval;/** 充电图标轨迹 */private Path chargingPath;/** 充电图标的颜色 */private int chargingColor;/** 是否显示充电图标(默认是不显示) */private boolean showChargingIcon = false;public RoundProgressBar(Context context) {this(context, null);}public RoundProgressBar(Context context, AttributeSet attrs) {this(context, attrs, 0);}public RoundProgressBar(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);//加载xml自定义属性TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgressBar);defaultRoundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_defaultRoundColor, Color.BLACK);roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN);percenTextColor = mTypedArray.getColor(R.styleable.RoundProgressBar_percenTextColor, Color.WHITE);percenTextSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_percenTextSize, 38);//充电文字内容electriText = context.getString(R.string.charging);electriTextColor = mTypedArray.getColor(R.styleable.RoundProgressBar_electriTextColor, Color.WHITE);electriTextSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_electriTextSize, 18);chargingColor = mTypedArray.getColor(R.styleable.RoundProgressBar_chargingColor, Color.GREEN);Util.dip2px(context, roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 15));max = mTypedArray.getInteger(R.styleable.RoundProgressBar_max, 100);mTypedArray.recycle();//使用缓存init();}/** * 初始化 */private void init(){setLayerType(LAYER_TYPE_SOFTWARE, null);defaultRoundPaint = new Paint();defaultRoundPaint.setAntiAlias(true);defaultRoundPaint.setColor(defaultRoundColor); defaultRoundPaint.setStyle(Paint.Style.STROKE); defaultRoundPaint.setStrokeWidth(roundWidth); progresRoundPaint = new Paint();progresRoundPaint.setAntiAlias(true);progresRoundPaint.setColor(roundProgressColor);progresRoundPaint.setStyle(Paint.Style.STROKE); progresRoundPaint.setStrokeWidth(roundWidth);percenTextPaint = new Paint();percenTextPaint.setAntiAlias(true);percenTextPaint.setColor(percenTextColor);percenTextPaint.setStyle(Style.FILL);percenTextPaint.setTextSize(percenTextSize);electriTextPaint = new Paint();electriTextPaint.setAntiAlias(true);electriTextPaint.setColor(electriTextColor);electriTextPaint.setStyle(Style.FILL);electriTextPaint.setTextSize(electriTextSize);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//计算中心点int centre = getWidth() / 2;//计算半径int radius = (int) (centre - roundWidth / 2);//绘制默认环形进度canvas.drawCircle(centre, centre, radius, defaultRoundPaint); //绘制环形进度if (oval == null) {oval = new RectF(centre - radius, centre - radius,centre + radius, centre + radius);}canvas.drawArc(oval, -90, 360 * progress / max, false, progresRoundPaint);//先判断是否是充电if(showChargingIcon){//绘制正在充电图标canvas.save();canvas.clipPath(drawPath(getWidth()));// 先画好轨迹canvas.drawColor(chargingColor);canvas.restore();}else{int Offset = 0;if(showElectriText){Offset = 30;}//绘制进度值文字int percent = progress * 100 / max; float percenTextWidth = percenTextPaint.measureText(percent + "%");   canvas.drawText(percent + "%", centre - percenTextWidth / 2, centre + (percenTextSize / 2) - Offset, percenTextPaint);if(showElectriText){//绘制电量文字float electriTextWidth = electriTextPaint.measureText(electriText);canvas.drawText(electriText, centre - electriTextWidth / 2, centre + (electriTextSize / 2) + Offset, electriTextPaint);}}}/** * 绘制充电图标轨迹 * @param width */private Path drawPath(int width){int avg = width/12;if(chargingPath == null){chargingPath = new Path();}chargingPath.moveTo(avg * 7, avg * 2);chargingPath.lineTo((avg * 6)+(avg/2), avg * 5);chargingPath.lineTo(avg * 8, avg * 5);chargingPath.lineTo(avg * 5, avg * 10);chargingPath.lineTo((avg * 5)+(avg/2), avg * 7);chargingPath.lineTo(avg * 4, avg * 7);chargingPath.close();return chargingPath;}/** * 设置圆形进度的最大值 * @param max */public void setMax(int max) {if(max < 0){max = 100;//默认为100}this.max = max;}/** * 设置进度值 * @param progress */public void setProgress(int progress) {if(progress < 0){progress = 0;}if(progress > max){progress = max;}if(progress <= max){this.progress = progress;postInvalidate();}}/** * 设置圆环进度的宽度 * @param roundWidth */public void setRoundWidth(float roundWidth) {this.roundWidth = roundWidth;}/** * 设置进度的背景颜色(底色) * @param cricleColor */public void setDefaultRoundColor(int cricleColor) {this.defaultRoundColor = cricleColor;}/** * 设置进度的颜色 * @param roundProgressColor */public void setRoundProgressColor(int roundProgressColor) {this.roundProgressColor = roundProgressColor;}/** * 设置百分比字体的颜色 * @param percenTextColor */public void setPercenTextColor(int percenTextColor) {this.percenTextColor = percenTextColor;}/** * 设置百分比字体大小 * @param percenTextSize */public void setPercenTextSize(float percenTextSize) {this.percenTextSize = percenTextSize;}/** * 设置是否显示电量文字 * @param showElectriText */public void setShowElectriText(boolean showElectriText){this.showElectriText = showElectriText;postInvalidate();}/** * 设置是否显示充电图标 * @param showChargingIcon */public void setShowChargingIcon(boolean showChargingIcon){this.showChargingIcon = showChargingIcon;postInvalidate();}}

MainActivity.java类

package com.qiulong.roundprogressbar;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import com.qiulong.circlepregress.R;public class MainActivity extends Activity {private RoundProgressBar mRoundProgressBar2;private Button btn1, btn2, btn3;private int progress = 0;private boolean running = false;private boolean one = true;private boolean two = true;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_cricle_progress);mRoundProgressBar2 = (RoundProgressBar) findViewById(R.id.roundProgressBar2);btn1 = (Button) findViewById(R.id.button1);btn2 = (Button) findViewById(R.id.button2);btn3 = (Button) findViewById(R.id.button3);btn1.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if(!running){Init();}}});btn2.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if(one){mRoundProgressBar2.setShowElectriText(true);one = false;btn2.setText("隐藏电量");}else{mRoundProgressBar2.setShowElectriText(false);one = true;btn2.setText("显示电量");}}});btn3.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {if(two){mRoundProgressBar2.setShowChargingIcon(true);two = false;btn2.setText("隐藏图标");}else{mRoundProgressBar2.setShowChargingIcon(false);two = true;btn2.setText("显示图标");}}});}private void Init() {progress = 0;Thread s = new Thread(runble);s.start();}/** 用于更新UI进度及数据 */private Runnable runble = new Runnable() {public void run() {running = true;while (progress <= 83) {// 转换为360的百分比mRoundProgressBar2.setProgress(progress);progress++;try {Thread.sleep(30);} catch (InterruptedException e) {e.printStackTrace();}}running = false;}};}

xml布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res/com.qiulong.circlepregress"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@color/theme_background"    android:gravity="center_horizontal"    android:orientation="vertical" >    <LinearLayout        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_marginTop="20dip"        android:gravity="center_horizontal"        android:orientation="horizontal" >        <Button            android:id="@+id/button1"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="加载进度" />        <Button            android:id="@+id/button2"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="显示电量" />        <Button            android:id="@+id/button3"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="显示图标" />    </LinearLayout>    <com.qiulong.roundprogressbar.RoundProgressBar        android:id="@+id/roundProgressBar2"        android:layout_width="200dip"        android:layout_height="200dip"        android:layout_marginTop="30dip"        app:chargingColor="@color/theme_green"        app:defaultRoundColor="@color/down_background"        app:electriTextColor="@color/white"        app:electriTextSize="20sp"        app:max="100"        app:percenTextColor="@color/white"        app:percenTextSize="48sp"        app:roundProgressColor="@color/theme_green"        app:roundWidth="20dip" /></LinearLayout>

最后一个自定义属性xml文件

<?xml version="1.0" encoding="UTF-8"?><resources>    <declare-styleable name="RoundProgressBar">        <attr name="defaultRoundColor" format="color" />        <attr name="roundProgressColor" format="color" />        <attr name="roundWidth" format="dimension"></attr>        <attr name="percenTextColor" format="color" />        <attr name="percenTextSize" format="dimension" />        <attr name="electriTextColor" format="color" />        <attr name="electriTextSize" format="dimension" />        <attr name="chargingColor" format="color" />        <attr name="max" format="integer"></attr>    </declare-styleable></resources>

OK!希望对大家有所帮助,不懂的朋友欢迎提问,下面是demo下载地址:

http://download.csdn.net/detail/baidu_23478311/8752507

转载请注明出处!


0 0