<?xml version="1.0" encoding="UTF-8"?>
<resources>
<!-- 显示的百分比(字) -->
<attr name="titleText" format="string" />
<!-- 显示的百分比字体(颜色) -->
<attr name="titleTextColor" format="color" />
<!-- 显示的百分比字体(大小) -->
<attr name="titleTextSize" format="dimension" />
<!-- 显示的整圈(颜色) -->
<attr name="firstColor" format="color" />
<!-- 显示的百分比圈(颜色) -->
<attr name="secondColor" format="color" />
<!-- 显示的空心圆的大小 -->
<attr name="circleWidth" format="dimension" />
<!-- 表示的进度值 -->
<attr name="mprogress" format="integer" />
<!-- 自定义ProgressBar -->
<declare-styleable name="CustomProgressBar">
<attr name="firstColor" />
<attr name="secondColor" />
<attr name="circleWidth" />
<attr name="titleText" />
<attr name="titleTextColor" />
<attr name="titleTextSize" />
<attr name="mprogress" />
</declare-styleable>
</resources>
1.在资源文件中设置自定义属性。
package com.cn.widget;
import com.cn.demo.R;
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.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
/**
* 自定义带设置百分比的静态ProgressBar
*
* @author hebiwen
*
*/
public class CustomProgressBar extends View {
private final static String TAG = "CustomProgressBar";
/**
* 第一个圈圈的颜色
*/
private int mFirstColor;
/**
* 第二个圈圈的颜色
*/
private int mSecondColor;
/**
* 圈的宽度
*/
private int mCircleWidth;
/**
* 表示的百分比
*/
private int mProgress;
private Paint mPaint;
private String mTitleText;
private int mTitleTextColor;
private int mTitleTextSize;
/**
* 计算文字所绘制的区域
*/
private Rect mTextBound;
private Paint mTextPaint;
public CustomProgressBar(Context context) {
this(context, null);
}
public CustomProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.CustomProgressBar, defStyle, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.CustomProgressBar_firstColor:
mFirstColor = a.getColor(attr, Color.GREEN);
break;
case R.styleable.CustomProgressBar_secondColor:
mSecondColor = a.getColor(attr, Color.RED);
break;
case R.styleable.CustomProgressBar_circleWidth:
mCircleWidth = a.getDimensionPixelSize(attr, (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20,
getResources().getDisplayMetrics()));
break;
case R.styleable.CustomProgressBar_titleText:
mTitleText = a.getString(attr);
break;
case R.styleable.CustomProgressBar_titleTextColor:
mTitleTextColor = a.getColor(attr, Color.RED);
break;
case R.styleable.CustomProgressBar_titleTextSize:
mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20,
getResources().getDisplayMetrics()));
break;
case R.styleable.CustomProgressBar_mprogress:
mProgress = a.getInt(attr, 0);
break;
default:
break;
}
}
// 此方法必须写
a.recycle();
mPaint = new Paint();
mTextBound = new Rect();
mTextPaint = new Paint();
mTextPaint.setTextSize(mTitleTextSize);
mTextPaint.setColor(mTitleTextColor);
// 计算描绘字体所需要的范围
mTextPaint
.getTextBounds(mTitleText, 0, mTitleText.length(), mTextBound);
}
@Override
protected void onDraw(Canvas canvas) {
int centerX = getWidth() / 2;// 获得圆心的x坐标
int centerY = getHeight() / 2;// 获得圆心的y坐标
int radius = centerX - mCircleWidth / 2;// 半径
mPaint.setStrokeWidth(mCircleWidth);// 设置园的直径
mPaint.setAntiAlias(true);// 消除锯齿
mPaint.setStyle(Paint.Style.STROKE);// 设置为空心
RectF oval = new RectF(centerX - radius, centerX - radius, centerX
+ radius, centerX + radius);// 用于定义圆弧的形状和大小的界限
mPaint.setColor(mFirstColor);
canvas.drawCircle(centerX, centerX, radius, mPaint);// 画出圆环
mPaint.setColor(mSecondColor);
canvas.drawArc(oval, 0, mProgress, false, mPaint);// 根据进度画圆弧
//计算文字的起始点
//计算baseline(参考文献) http://blog.csdn.net/sirnuo/article/details/21165665
FontMetrics fontMetrics = mTextPaint.getFontMetrics();
float descentY = centerY + fontMetrics.descent;
// 设置字符串的左边在屏幕的中间
mTextPaint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(mTitleText, centerX, descentY, mTextPaint);
Log.i(TAG, "center(" + centerX + "," + centerY + ")");
Log.i(TAG,
"mTextBound(" + mTextBound.centerX() / 2 + ","
+ mTextBound.centerY() / 2 + ")");
}
}
2.新建类CustomProgressBar继承View
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:hbw="http://schemas.android.com/apk/res/com.cn.demo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<com.cn.widget.CustomProgressBar
android:layout_width="120dp"
android:layout_height="120dp"
hbw:circleWidth="20dp"
hbw:firstColor="#999999"
hbw:secondColor="#FE9900"
hbw:titleText="30%"
hbw:titleTextColor="#FE9900"
hbw:titleTextSize="22sp"
hbw:mprogress="108" />
<com.cn.widget.CustomProgressBar
android:layout_width="200dp"
android:layout_height="200dp"
hbw:circleWidth="25dp"
hbw:firstColor="#999999"
hbw:secondColor="#FE9900"
hbw:titleText="60%"
hbw:titleTextColor="#FE9900"
hbw:titleTextSize="22sp"
hbw:mprogress="216" />
</LinearLayout>
3.在XMl文件中使用。
效果图
参考文献
Android 自定义View (三) 圆环交替 等待效果
关于Android Canvas.drawText方法中的坐标参数的正确解释