package UICtrl; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Canvas; import android.view.animation.Interpolator; import android.graphics.Paint; import android.graphics.PointF; import android.os.Build; import android.util.AttributeSet; import android.view.ViewGroup; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.view.animation.LinearInterpolator; import android.widget.RelativeLayout; /** * Created by wangchaomac on 2017/10/18. */ public class AroundCircleBall extends RelativeLayout { private BallView mBall; //角度 private float mBallRadius; //小球的颜色 private int mBallColor; private int mCircleRadius; private int mCircleColor; private int mDuration; //笔头描宽 private float mStrokeWidth; private int mInterpolator; private final int ACCELERATE_DECELERATE_INTERPOLATOR = 1; private final int LINEAR_INTERPOLATOR = 2; private final int ACCELERATE = 3; private final int DECELERATE = 4; ObjectAnimator mRotateAnim; PointF mCircleCenterPoint = new PointF(mCircleRadius + mBallRadius, mCircleRadius + mBallRadius); Paint mPaint = new Paint(); public AroundCircleBall(Context context, AttributeSet attrs){ super(context, attrs); // TODO Auto-generated constructor stub init(context); } private void init(Context context){ init(); } private void init() { mBall = new BallView(getContext()); mBall.setRadius(mBallRadius); mBall.setBallColor(mBallColor); //小球的初始位置在圆环的最底部 LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); params.leftMargin = (int) (mCircleRadius); params.topMargin = (int) (mCircleRadius * 2); mBall.setLayoutParams(params); addView(mBall); } @Override protected void onDraw(Canvas canvas) { //绘制圆 mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(mStrokeWidth); mPaint.setColor(mCircleColor); canvas.drawCircle(mCircleCenterPoint.x, mCircleCenterPoint.y, mCircleRadius, mPaint); super.onDraw(canvas); } protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //测量控件宽高 int width = (int) (getPaddingLeft() + mCircleRadius * 2 + mBallRadius * 2 + getPaddingRight()); int height = (int) (getPaddingTop() + mCircleRadius * 2 + mBallRadius * 2 + getPaddingBottom()); setMeasuredDimension(width, height); } private void initRotateAnim(){ mRotateAnim = ObjectAnimator.ofFloat(mBall, "rotation", 0f, 360f); //计算小球旋转的中心点(此点的左边是在小球自身的坐标系中) float pivotX = mBall.getRadius(); float pivotY = mBall.getRadius() - mCircleRadius; mBall.setPivotX(pivotX); mBall.setPivotY(pivotY); mRotateAnim.setDuration(mDuration); mRotateAnim.setInterpolator(getInterpolator()); mRotateAnim.setRepeatCount(-1); mRotateAnim.setStartDelay(500); } private Interpolator getInterpolator(){ Interpolator interpolator = null; switch (mInterpolator){ case ACCELERATE_DECELERATE_INTERPOLATOR: //先加上后减速 interpolator = new AccelerateDecelerateInterpolator(); break; case LINEAR_INTERPOLATOR: //匀速 interpolator = new LinearInterpolator(); break; case ACCELERATE: //加速 interpolator = new AccelerateInterpolator(); break; case DECELERATE: //减速 interpolator = new DecelerateInterpolator(); break; } return interpolator; } /** * 启动旋转动画 */ public void startRotate(){ if (mRotateAnim != null){ mRotateAnim.start(); } } /** * 暂停旋转动画 */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) public void pauseRotate(){ if (mRotateAnim != null && mRotateAnim.isRunning()){ mRotateAnim.pause(); } } /** * 取消旋转动画 */ public void cancelRotate(){ if (mRotateAnim != null){ mRotateAnim.cancel(); } } }
package UICtrl; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PointF; import android.util.AttributeSet; import android.view.View; /** * Created by wangchaomac on 2017/10/18. */ public class BallView extends View { private int mBallColor = Color.BLACK; private float mRadius = 10f; private PointF mCenterPoint; private Paint mPaint; public BallView(Context context) { this(context, null); } public BallView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init(){ mPaint = new Paint(); mPaint.setAntiAlias(true); mCenterPoint = new PointF(mRadius, mRadius); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = (int) (getPaddingLeft() + 2*mRadius + getPaddingRight()); int height = (int) (getPaddingTop() + 2*mRadius + getPaddingBottom()); setMeasuredDimension(width, height); } @Override protected void onDraw(Canvas canvas) { mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(mBallColor); canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mRadius, mPaint); } public void setBallColor(int mBallColor) { this.mBallColor = mBallColor; } public void setRadius(float radius) { this.mRadius = radius; mCenterPoint.set(radius, radius); } public float getRadius() { return mRadius; } }