概述
自定义View画一个类似下图的圆环:
分为三步:画底部圆,上层圆,还有文字
其中上层圆需要渐变颜色,并且和数字代表的程度统一。
代码如下:
public class ScoreCircle extends View {
private static final String TAG = "ScoreCircleLog";
private int circleRadius;//圆半径
private int circleStroke;//线宽
private int totalSize;//View总大小
private int padding;
private int firstCircleColor;
private int secondStartColor;
private int secondEndColor;
private SweepGradient mGradient;
private Matrix gradientMatrix;
private int frontColor;
private int frontSize;
private int totalAngle = 349;//最多只能转350度,不然会重合
private float totalScore = 100f; //总分100
private float currentScore = 60f;//
private DecimalFormat decimalFormat=new DecimalFormat(".0");
private Paint mPaint;
public ScoreCircle(Context context) {
super(context);
}
public ScoreCircle(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public ScoreCircle(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(attrs,context);
initPaint();
}
private void initAttrs(AttributeSet attrs,Context context) {
TypedArray typedArray = this.getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.ScoreCircle, 0, 0);
try {
int width = typedArray.getLayoutDimension(R.styleable.ScoreCircle_android_layout_width, (int) this.getResources().getDimension(R.dimen.scoreCircle_size));
int height = typedArray.getLayoutDimension(R.styleable.ScoreCircle_android_layout_height, (int)this.getResources().getDimension(R.dimen.scoreCircle_size));
setTotalSize(width,height);
padding = (int) typedArray.getDimension(R.styleable.ScoreCircle_padding, this.getResources().getDimension(R.dimen.scoreCircle_padding));
circleStroke = (int) typedArray.getDimension(R.styleable.ScoreCircle_stroke, this.getResources().getDimension(R.dimen.scoreCircle_stroke));
firstCircleColor = typedArray.getColor(R.styleable.ScoreCircle_firstCircleColor,ContextCompat.getColor(context,R.color.ScoreCircle_first_color));
secondStartColor = typedArray.getColor(R.styleable.ScoreCircle_sendColorStart,ContextCompat.getColor(context,R.color.ScoreCircle_second_start));
secondEndColor = typedArray.getColor(R.styleable.ScoreCircle_sendColorEnd,ContextCompat.getColor(context,R.color.ScoreCircle_second_end));
frontColor = typedArray.getColor(R.styleable.ScoreCircle_front_color,ContextCompat.getColor(context,R.color.ScoreCircle_front_color));
frontSize = (int) typedArray.getDimension(R.styleable.ScoreCircle_front_size,AppUtils.dpToPx(context,22));
} finally {
typedArray.recycle();
}
}
public void setScore(float score) {
if (score > 100)
score = 100;
if (score < 0)
score = 0;
this.currentScore = score;
invalidate();
}
private void setTotalSize(int width,int height){
if (width == WRAP_CONTENT || width == MATCH_PARENT){
if (width == WRAP_CONTENT){
totalSize = (int)this.getResources().getDimension(R.dimen.scoreCircle_size);
}
}else {
if (width > height){
totalSize = width;
}else
totalSize = height;
}
}
private void initPaint(){
mPaint = new Paint();
mGradient = new SweepGradient(0,0,secondStartColor,secondEndColor);
gradientMatrix = new Matrix();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
totalSize = resolveSize(totalSize,widthMeasureSpec);
circleRadius = totalSize/2 - padding - circleStroke/2;
setMeasuredDimension(totalSize,totalSize);
}
// invalidate(); ondraw
// requestLayout(); onMeasure onlayout
@Override
protected void onDraw(Canvas canvas) {
drawFirstCircle(canvas);
drawSecondCircle(canvas);
drawText(canvas);
}
//底部圆
private void drawFirstCircle(Canvas canvas) {
mPaint.reset();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(circleStroke);
mPaint.setColor(firstCircleColor);
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(totalSize/2,totalSize/2,circleRadius,mPaint);
}
//表层圆
@SuppressLint("NewApi")
private void drawSecondCircle(Canvas canvas) {
mPaint.reset();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(circleStroke+2);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setShader(mGradient);
float angle = (currentScore / totalScore)*totalAngle;
canvas.save();
gradientMatrix.setTranslate(totalSize/2,totalSize/2);
mGradient.setLocalMatrix(gradientMatrix);
// gradientMatrix.setRotate(0.9f,totalSize/2,totalSize/2);
canvas.rotate(-90,totalSize/2,totalSize/2);
// mGradient.setLocalMatrix(gradientMatrix);
canvas.drawArc(padding+circleStroke/2, padding+circleStroke/2 ,
totalSize - padding-circleStroke/2, totalSize - padding-circleStroke/2,
6,angle,false,mPaint
);
canvas.restore();
}
//中间文字
private void drawText(Canvas canvas) {
mPaint.reset();
mPaint.setAntiAlias(true);
mPaint.setFakeBoldText(true);
Rect textBounds = new Rect();
String score = decimalFormat.format(currentScore);
mPaint.setTextSize(frontSize);
frontColor = ContextCompat.getColor(getContext(),R.color.ScoreCircle_front_color);
mPaint.setColor(frontColor);
mPaint.getTextBounds(score,0,score.length(),textBounds);
canvas.drawText(score,totalSize/2 - textBounds.width()/2 - textBounds.left,
totalSize/2 + textBounds.height()/2 - textBounds.bottom ,mPaint);
}
这样就可以画出来,但是还有zu最后一部,保存画过的状态,
@Nullable
@Override
protected Parcelable onSaveInstanceState() {
Parcelable parcelable = super.onSaveInstanceState();
SavedState savedState = new SavedState(parcelable);
savedState.SavedCurrentScore = currentScore;
return savedState;
}
private static class SavedState extends BaseSavedState{
float SavedCurrentScore;
public SavedState(Parcel source) {
super(source);
SavedCurrentScore = source.readFloat();
}
public SavedState(Parcelable superState) {
super(superState);
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeFloat(SavedCurrentScore);
}
public static final Creator<SavedState> CREATOR = new Creator<SavedState>(){
@Override
public SavedState createFromParcel(Parcel source) {
return new SavedState(source);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
这样View重绘的时候状态不会变掉。
最后
以上就是完美花卷为你收集整理的android 画一个渐变的圆环的全部内容,希望文章能够帮你解决android 画一个渐变的圆环所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复