paint也是画笔,可以再canvas上绘制任意的点、线、形、色等,熟练使用paint可以组装出很漂亮的自定义控件,下面用piant画了一个简单的加载进度
绘制的时候要注意文字的宽度和位置,而是使用paint的style,比如描边,填充等。
先看布局文件和attrs属性代码
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="PaintProgress">
<attr name="textSize" format="dimension" />
<attr name="textColor" format="color" />
<!--是否显示百分号-->
<attr name="showPercent" format="boolean" />
<!--进度条的颜色-->
<attr name="roundColor" format="color" />
<!--圆环的宽度-->
<attr name="roundWidth" format="dimension" />
<!--当前进度-->
<attr name="progress" format="integer" />
<!--内圆的半径-->
<attr name="circleRadius" format="dimension" />
</declare-styleable>
</resources>
<com.example.administrator.meterialdesignpaintdemo.PaintProgress
android:id="@+id/progressBar"
android:layout_width="match_parent"
android:layout_height="400dp"
app:roundColor="@color/colorAccent"
app:roundWidth="10dp"
app:showPercent="true"
app:textColor="@color/colorPrimary"
app:circleRadius="60dp"
app:textSize="40sp" />
接下来是控件的代码
public class PaintProgress extends View {
final String TAG = "==test==";
private final boolean showPercent;
private final float roundWidth;
private final int roundColor;
private int progress;
private final Paint textPaint;
private String drawnText = "";
private int cX;
private int cY;
private final Paint arcPaint;
private final Paint paint;
private int circleRaidus;
public PaintProgress(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PaintProgress);
showPercent = typedArray.getBoolean(R.styleable.PaintProgress_showPercent, true);
roundWidth = typedArray.getDimension(R.styleable.PaintProgress_roundWidth, 6);
roundColor = typedArray.getColor(R.styleable.PaintProgress_roundColor, Color.RED);
progress = typedArray.getInteger(R.styleable.PaintProgress_progress, 0);
float textSize = typedArray.getDimension(R.styleable.PaintProgress_textSize, 20);
int textColor = typedArray.getColor(R.styleable.PaintProgress_textColor, Color.BLACK);
circleRaidus= (int) typedArray.getDimension(R.styleable.PaintProgress_circleRadius,80);
Log.i(TAG, "PaintProgress: ==" + textSize);
typedArray.recycle();
textPaint = new Paint();
textPaint.setColor(textColor);
textPaint.setTextSize(textSize);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(roundColor);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(roundWidth);
arcPaint = new Paint();
arcPaint.setStrokeWidth(roundWidth);
arcPaint.setColor(Color.BLUE);
arcPaint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//尺寸测量方面不考虑细致
cX = MeasureSpec.getSize(widthMeasureSpec) / 2;
cY = MeasureSpec.getSize(heightMeasureSpec) / 2;
Log.i(TAG, "onMeasure: 测量结果=" + cX + " , " + cY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//首先画一个圆环
Log.i(TAG, "onDraw: 开始绘制");
canvas.drawCircle(cX, cY, circleRaidus+roundWidth, paint);
//开始绘制中间文字
if (showPercent) {
drawnText = progress + "%";
} else {
drawnText = progress + "";
}
float textWidth = textPaint.measureText(drawnText);
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float ctY = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
canvas.drawText(drawnText, cX - textWidth / 2, ctY + cY, textPaint);
//绘制转动圆弧
/**
* @param oval 园的矩形
* @param startAngle 角度
* @param sweepAngle 增加的角度
* @param useCenter 是否填充绘制的整个扇形要注意和piant的sytle相互搭配
* @param paint The paint used to draw the arc
*/
RectF oval = new RectF(cX -(circleRaidus+roundWidth), cY - (circleRaidus+roundWidth), cX + circleRaidus+roundWidth, cY +circleRaidus+roundWidth);
canvas.drawArc(oval, 0f, 360*progress/100, false, arcPaint);
}
public synchronized void setProgress( int progress){
this.progress=progress;
postInvalidate();
}
}
备注:下面是踩坑发生的效果:
//如果将是否填充更改为ture,效果图如下
canvas.drawArc(oval, 0f, 360*progress/100, true, arcPaint);
//如果将是否填充更改为ture,且paint也设置为填充呢?
arcPaint.setStyle(Paint.Style.FILL);
canvas.drawArc(oval, 0f, 360*progress/100, true, arcPaint);
//不填充扇形的效果
Paint arcPaint = new Paint();
arcPaint.setStrokeWidth(roundWidth);
arcPaint.setColor(Color.BLUE);
canvas.drawArc(oval, 0f, 360 * progress / 100, false, arcPaint);