包包网站建设什么是搜索引擎营销?
自定义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; //总分100private 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;}elsetotalSize = height;}}private void initPaint(){mPaint = new Paint();mGradient = new SweepGradient(0,0,secondStartColor,secondEndColor);gradientMatrix = new Matrix();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {totalSize = resolveSize(totalSize,widthMeasureSpec);circleRadius = totalSize/2 - padding - circleStroke/2;setMeasuredDimension(totalSize,totalSize);}// invalidate(); ondraw// requestLayout(); onMeasure onlayout@Overrideprotected 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@Overrideprotected 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);}@Overridepublic void writeToParcel(Parcel out, int flags) {super.writeToParcel(out, flags);out.writeFloat(SavedCurrentScore);}public static final Creator<SavedState> CREATOR = new Creator<SavedState>(){@Overridepublic SavedState createFromParcel(Parcel source) {return new SavedState(source);}@Overridepublic SavedState[] newArray(int size) {return new SavedState[size];}};}}
这样View重绘的时候状态不会变掉。