1、res---->values文件夹下添加文件attrs.xml详情如下:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="SuccessView"> <attr name="svStrokeColor" format="color|reference" /> <attr name="svStrokeWidth" format="float" /> </declare-styleable> </resources>
2、自定义操作成功动画
/** * 作者:created by meixi * 邮箱:13164716840@163.com * 日期:2018/9/6 09 */ public class MySuccessView extends View { private float mDensity = -1; private Paint mPaint, nPaint; private float minWidth;//动画大小 private float minHeight; private float angle, startAngle = -90; private final float CONST_RADIUS = dip2px(1.2f); private final float CONST_RECT_WEIGHT = dip2px(3); private final float CONST_LEFT_RECT_W = dip2px(15); private final float CONST_RIGHT_RECT_W = dip2px(25); private float mLeftRectWidth = 0; private float mRightRectWidth = 0; public MySuccessView(Context context) { this(context, null); } public MySuccessView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MySuccessView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(attrs); } private void init(AttributeSet attrs) { TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.SuccessView); int pColor = typedArray.getColor(R.styleable.SuccessView_svStrokeColor, 0xffA5DC86); float strokeWidth = typedArray.getFloat(R.styleable.SuccessView_svStrokeWidth, 2.5f); typedArray.recycle(); //should recycle minWidth = dip2px(50); minHeight = dip2px(50); mPaint = new Paint(); mPaint.setColor(pColor); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setStrokeWidth(0.8f); mPaint.setAntiAlias(true); nPaint = new Paint(); nPaint.setAntiAlias(true); nPaint.setStyle(Paint.Style.STROKE); nPaint.setStrokeWidth(dip2px(strokeWidth)); nPaint.setColor(pColor); } @Override protected void onDraw(Canvas canvas) { Rect bounds = canvas.getClipBounds(); float left, right, top, bottom; if (bounds.width() > bounds.height()) { float distance = (bounds.width() / 2 - bounds.height() / 2); left = bounds.left + distance; right = bounds.right - distance; top = bounds.top; bottom = bounds.bottom; } else if (bounds.width() < bounds.height()) { float distance = (bounds.height() / 2 - bounds.width() / 2); top = bounds.top + distance; bottom = bounds.bottom - distance; left = bounds.left; right = bounds.right; } else { left = bounds.left; right = bounds.right; top = bounds.top; bottom = bounds.bottom; } RectF oval = new RectF(left + dip2px(2f), top + dip2px(2f), right - dip2px(2f), bottom - dip2px(2f)); canvas.drawArc(oval, startAngle, angle, false, nPaint); int totalW = getWidth(); int totalH = getHeight(); canvas.rotate(45, totalW / 2, totalH / 2); totalW /= 1.2; totalH /= 1.4; RectF leftRect = new RectF(); if (mLeftRectWidth > 0) { leftRect.left = (totalW - CONST_LEFT_RECT_W) / 2 + CONST_RECT_WEIGHT; leftRect.right = leftRect.left + dip2px(mLeftRectWidth); leftRect.top = (totalH + CONST_RIGHT_RECT_W) / 2; leftRect.bottom = leftRect.top + CONST_RECT_WEIGHT; canvas.drawRoundRect(leftRect, CONST_RADIUS, CONST_RADIUS, mPaint); } if (mRightRectWidth > 0) { RectF rightRect = new RectF(); rightRect.bottom = (totalH + CONST_RIGHT_RECT_W) / 2 + CONST_RECT_WEIGHT - 1; rightRect.left = (totalW + CONST_LEFT_RECT_W) / 2; rightRect.right = rightRect.left + CONST_RECT_WEIGHT; rightRect.top = rightRect.bottom - dip2px(mRightRectWidth); canvas.drawRoundRect(rightRect, CONST_RADIUS, CONST_RADIUS, mPaint); } super.onDraw(canvas); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width; int height; if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { width = (int) (getPaddingLeft() + minWidth + getPaddingRight()); } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { height = (int) (getPaddingTop() + minHeight + getPaddingBottom()); } setMeasuredDimension(width, height); } public float dip2px(float dpValue) { if (mDensity == -1) { mDensity = getResources().getDisplayMetrics().density; } return dpValue * mDensity + 0.5f; } public void startAnim(int startDelay) { clearAnimation(); ValueAnimator animator = ValueAnimator.ofFloat(0, 60f, 120f, 180f, 240f, 300f, 360f, 375f, 400f); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { float value = (float) valueAnimator.getAnimatedValue(); angle = -value; if (value>360 && value<=375){ mLeftRectWidth = value - 360; }else if(value>375){ mRightRectWidth = value - 375; } invalidate(); } }); animator.setDuration(1000); animator.setInterpolator(new LinearInterpolator()); animator.setStartDelay(startDelay); animator.start(); } } 3、activity调用
3、activity 调用自定义操作成功动画
<com.administrator.tests.MySuccessView android:id="@+id/view" android:layout_width="wrap_content" android:layout_height="wrap_content" app:svStrokeColor="@color/colorPrimary" />
MySuccessView sv =(MySuccessView)findViewById(R.id.view) ; sv.startAnim(200);