1、最终的效果图
2、设计思路和用到知识点
2.1 了解自定义组件的实现的基本流程,这里重写了onMeasure和onDraw方法
2.2 计算文字的高度和宽度
2.3 对canvas的基本方法
2.4 通过handler进行发送消息,响应inValidate方法,然后刷新界面
源代码:
package com.example.canvastest.image;
import com.example.canvastest.R;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
public class CircleView extends View {
//半径
private float radius = 100;
private Paint mDownPaint;
//宽度
private float mCirclePaintWidth = 20;
//圆心坐标
private int x;
private int y;
//上面圆圈的画笔
private Paint mUpPaint;
//画文字
private Paint mTextPaint;
//文字高度
private int textHeight;
//文字大小
private int textFontSize = 14;
public CircleView(Context context) {
super(context);
init();
}
public CircleView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mDownPaint = new Paint();
mDownPaint.setColor(Color.GRAY);
mDownPaint.setAntiAlias(true);
mDownPaint.setStrokeWidth(mCirclePaintWidth);
mDownPaint.setStyle(Style.STROKE);
// 上面的画笔
mUpPaint = new Paint();
mUpPaint.setAntiAlias(true);
mUpPaint.setStrokeWidth(mCirclePaintWidth);
mUpPaint.setStyle(Style.STROKE);
mUpPaint.setColor(Color.GREEN);
// 上面的画笔
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setColor(Color.BLACK);
textFontSize = (int) getResources().getDimension(R.dimen.textSize);
mTextPaint.setTextSize(textFontSize);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
x = getMeasuredWidth() / 2;
y = getMeasuredHeight() / 2;
textHeight = (int) ((getHeight() - getFontHeight(mTextPaint)) / 2 - mTextPaint
.getFontMetrics().top);
mHandler.sendEmptyMessageAtTime(RUNNING, 100);
// System.out.println("--------------- " + textHeight+" "+mTextPaint.getFontMetrics().top);
// System.out.println("----meh--"+getMeasuredHeight()+"-----h--"+getHeight()+"---y "+y+" fonth "+getFontHeight(mTextPaint));
}
@Override
protected void onDraw(Canvas canvas) {
//画圆
canvas.drawCircle(x, y, radius, mDownPaint);
//设置文字
String text = (degree*100/360)+"%";
float textWidth = mTextPaint.measureText(text);
canvas.drawText(text, x - textWidth / 2, textHeight, mTextPaint);
//画的范围
RectF oval = new RectF(x - radius, y - radius, x + radius, y + radius);
canvas.drawArc(oval, -90, degree, false, mUpPaint);
super.onDraw(canvas);
}
/**
* 圆的角度
*/
private int degree = 0;
private static final int RUNNING = 10;
/**
* 是否循环执行
*/
private boolean isRecycle=false;
/**
* 刷新进度
*/
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case RUNNING:
if (degree>=360) {
if (isRecycle) {
degree =0;
mHandler.sendEmptyMessage(RUNNING);
invalidate();
}else {
mHandler.removeCallbacksAndMessages(null);
}
}else {
degree++;
Message oMessage = this.obtainMessage();
if (oMessage==null) {
oMessage = new Message();
System.out.println(" message is null");
}
oMessage.what=RUNNING;
oMessage.setTarget(this);
sendMessageDelayed(oMessage, 50);
invalidate();
}
break;
default:
break;
}
};
};
/**
* 获取字体的高度
*
* @param paint
* @return
*/
private int getFontHeight(Paint paint) {
FontMetrics fm = paint.getFontMetrics();
return (int) Math.ceil(fm.descent - fm.ascent);
}
/**
* 设置是否循环
* @param isRecycle
*/
public void setRecycle(boolean isRecycle) {
this.isRecycle = isRecycle;
}
}
3、自定义View文字居中
@Override
public void onDraw (Canvas canvas) {
Rect targetRect = new Rect(50, 50, 1000, 200);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStrokeWidth(3);
paint.setTextSize(80);
String testString = "测试:ijkJQKA:1234";
paint.setColor(Color.CYAN);
canvas.drawRect(targetRect, paint);
paint.setColor(Color.RED);
FontMetricsInt fontMetrics = paint.getFontMetricsInt();
// 转载请注明出处:http://blog.csdn.net/hursing
int baseline = targetRect.top + (targetRect.bottom - targetRect.top - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
// 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX()
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(testString, targetRect.centerX(), baseline, paint);
}
http://blog.csdn.net/hursing/article/details/18703599