應學弟要求,幫忙做的一個圓形動畫效果,UI是借鑑跑步停止按鈕實現的。
如圖所示:圓形按鈕,長按觸發進度條,鬆開取消,帶動畫效果。直接附上代碼。
public class HJProgressButton extends View {
// 畫實心圓的畫筆
private Paint mCirclePaint;
// 畫圓環的畫筆
private Paint mRingPaint;
// 畫圓環c3c3c3的畫筆
private Paint mRingC3Paint;
// 圓形顏色
private int mCircleColor;
// 圓環顏色
private int mRingColor;
// 圓環底顏色
private int mRingC3Color;
// 半徑
private float mRadius;
// 圓環半徑
private float mRingRadius;
// 大圓環半徑
private float mBigRingRadius;
// 圓環寬度
private float mStrokeWidth;
// 圓心x座標
private int mXCenter;
// 圓心y座標
private int mYCenter;
// 總進度
private int mTotalProgress = 300;
// 當前進度
private int mProgress;
private boolean isFinish;
public HJProgressButton(Context context, AttributeSet attrs) {
super(context, attrs);
// 獲取自定義的屬性
initAttrs(context, attrs);
initVariable();
this.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch ( event.getAction()){
case MotionEvent.ACTION_DOWN:
startAnimationProgress(300);
break;
case MotionEvent.ACTION_UP:
if(mProgress >= 300){
if(!isFinish){
mProgressButtonFinishCallback.onFinish();
return false;
}
}
if(mProgress != 300){
if(mProgress < 300){
stopAnimationProgress(mProgress);
mProgressButtonFinishCallback.onCancel();
}
}
break;
}
return false;
}
});
}
private void initAttrs(Context context, AttributeSet attrs) {
TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.TasksCompletedView, 0, 0);
mRadius = typeArray.getDimension(R.styleable.TasksCompletedView_radius, 80);
mStrokeWidth = typeArray.getDimension(R.styleable.TasksCompletedView_strokeWidth, 10);
mCircleColor = typeArray.getColor(R.styleable.TasksCompletedView_circleColor, 0xFFFFFFFF);
mRingColor = typeArray.getColor(R.styleable.TasksCompletedView_ringColor, 0xCCCCCC);
mRingC3Color = typeArray.getColor(R.styleable.TasksCompletedView_ringCColor, 0xCCCCCC);
mRingRadius = mRadius + mStrokeWidth;
mBigRingRadius = mRadius + mStrokeWidth * 2;
}
private void initVariable() {
mCirclePaint = new Paint();
mCirclePaint.setAntiAlias(true);
mCirclePaint.setColor(mCircleColor);
mCirclePaint.setStyle(Paint.Style.FILL);
mRingPaint = new Paint();
mRingPaint.setAntiAlias(true);
mRingPaint.setColor(mRingColor);
mRingPaint.setStyle(Paint.Style.STROKE);
mRingPaint.setStrokeWidth(mStrokeWidth);
mRingC3Paint = new Paint();
mRingC3Paint.setAntiAlias(true);
mRingC3Paint.setColor(mRingC3Color);
mRingC3Paint.setStyle(Paint.Style.STROKE);
mRingC3Paint.setStrokeWidth(mStrokeWidth - 2);
}
@Override
protected void onDraw(Canvas canvas) {
mXCenter = getWidth() / 2;
mYCenter = getHeight() / 2;
canvas.drawCircle(mXCenter, mYCenter, mBigRingRadius, mCirclePaint);
if(mProgress == 300){
RectF oval = new RectF();
oval.left = (mXCenter - mRingRadius);
oval.top = (mYCenter - mRingRadius);
oval.right = mRingRadius + mXCenter;
oval.bottom = mRingRadius + mYCenter;
canvas.drawArc(oval, -90, 360, false, mCirclePaint); //
}else if (mProgress > 0) {
RectF oval = new RectF();
oval.left = (mXCenter - mRingRadius);
oval.top = (mYCenter - mRingRadius);
oval.right = mRingRadius + mXCenter;
oval.bottom = mRingRadius + mYCenter;
canvas.drawArc(oval, -90, 360, false, mRingC3Paint);
canvas.drawArc(oval, -90, ((float) mProgress / mTotalProgress) * 360, false, mRingPaint); //
}
}
private ProgressButtonFinishCallback mProgressButtonFinishCallback;
public void setListener(ProgressButtonFinishCallback progressButtonFinishCallback){
mProgressButtonFinishCallback = progressButtonFinishCallback;
}
public interface ProgressButtonFinishCallback{
void onFinish();
void onCancel();
}
private ValueAnimator startAnimator;
private ValueAnimator stopAnimator;
//按壓開始
private void startAnimationProgress(int progress) {
isFinish = false;
if(null!=stopAnimator){
if(stopAnimator.isRunning()){
stopAnimator.cancel();
}
}
startAnimator = ValueAnimator.ofInt(0, progress);
startAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mProgress = (int) animation.getAnimatedValue();
invalidate();
if(mProgress >= 300){
if(!isFinish){
isFinish = true;
mProgressButtonFinishCallback.onFinish();
Log.v("startAnimationProgress", mProgress + "");
}
}
}
});
startAnimator.setInterpolator(new OvershootInterpolator());
startAnimator.setDuration(3000);
startAnimator.start();
}
//按壓結束
private void stopAnimationProgress(int progress) {
if(null!=startAnimator) {
if (startAnimator.isRunning()) {
startAnimator.cancel();
}
}
stopAnimator = ValueAnimator.ofInt(progress, 0);
stopAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mProgress = (int) animation.getAnimatedValue();
invalidate();
}
});
stopAnimator.setInterpolator(new OvershootInterpolator());
stopAnimator.setDuration(3000);
stopAnimator.start();
}
}
<declare-styleable name="TasksCompletedView">
<attr name="radius" format="dimension"/>
<attr name="strokeWidth" format="dimension"/>
<attr name="circleColor" format="color"/>
<attr name="ringColor" format="color"/>
<attr name="ringCColor" format="color"/>
</declare-styleable>
xml
<cn.gs.m2m.phone.widget.HJProgressButton
android:id="@+id/myProgressButton"
android:layout_centerInParent="true"
android:layout_width="105dp"
app:radius="45dp"
app:strokeWidth="3dp"
app:circleColor="#FF405C"
app:ringColor="@color/white"
app:ringCColor="#FA0C45"
android:layout_height="105dp"
android:clickable="true"/>
Activity
hjProgressButton.setListener(new HJProgressButton.ProgressButtonFinishCallback() {
@Override
public void onFinish() {
}
@Override
public void onCancel() {
}
});
很簡單的一個功能實現。