仿照58的加载动画,话不多说看效果图。
(1)实现代码
布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:my="http://schemas.android.com/apk/res/com.example.copy58loadingdemo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
>
<com.example.copy58loadingdemo.LoadingView
android:id="@+id/loadView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:layout_gravity="center" />
<com.example.copy58loadingdemo.MonIndicator
android:id="@+id/monIndicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="30dp"
my:circleRadius="14dp"
my:cycle="1500" />
</LinearLayout>
(2)LoadingView
package com.example.copy58loadingdemo;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
public class LoadingView extends FrameLayout {
private static final int ANIMATION_DURATION = 500;
private static float mDistance = 200;
private ShapeLoadingView mShapeLoadingView;
private ImageView mIndicationIm;
private TextView mLoadTextView;
private int mTextAppearance;
private String mLoadText;
public LoadingView(Context context) {
super(context);
}
public LoadingView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
TypedArray typedArray = context
.obtainStyledAttributes(attrs, R.styleable.LoadingView);
mLoadText = typedArray.getString(R.styleable.LoadingView_loadingText);
mTextAppearance = typedArray.getResourceId(R.styleable.LoadingView_loadingTextAppearance, -1);
typedArray.recycle();
}
public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
public int dip2px(float dipValue) {
final float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
View view = LayoutInflater.from(getContext()).inflate(R.layout.load_view, null);
mDistance = dip2px(54f);
LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.CENTER;
mShapeLoadingView = (ShapeLoadingView) view.findViewById(R.id.shapeLoadingView);
mIndicationIm = (ImageView) view.findViewById(R.id.indication);
mLoadTextView = (TextView) view.findViewById(R.id.promptTV);
if (mTextAppearance != -1) {
mLoadTextView.setTextAppearance(getContext(), mTextAppearance);
}
setLoadingText(mLoadText);
addView(view, layoutParams);
this.postDelayed(new Runnable() {
@Override
public void run() {
freeFall();
}
}, 900);
}
public void setLoadingText(CharSequence loadingText) {
if (TextUtils.isEmpty(loadingText)) {
mLoadTextView.setVisibility(GONE);
} else {
mLoadTextView.setVisibility(VISIBLE);
}
mLoadTextView.setText(loadingText);
}
@SuppressLint("NewApi")
public void upThrow() {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mShapeLoadingView, "translationY", mDistance, 0);
ObjectAnimator scaleIndication = ObjectAnimator.ofFloat(mIndicationIm, "scaleX", 0.2f, 1);
ObjectAnimator objectAnimator1 = null;
switch (mShapeLoadingView.getShape()) {
case SHAPE_RECT:
objectAnimator1 = ObjectAnimator.ofFloat(mShapeLoadingView, "rotation", 0, -120);
break;
case SHAPE_CIRCLE:
objectAnimator1 = ObjectAnimator.ofFloat(mShapeLoadingView, "rotation", 0, 180);
break;
case SHAPE_TRIANGLE:
objectAnimator1 = ObjectAnimator.ofFloat(mShapeLoadingView, "rotation", 0, 180);
break;
}
objectAnimator.setDuration(ANIMATION_DURATION);
objectAnimator1.setDuration(ANIMATION_DURATION);
objectAnimator.setInterpolator(new DecelerateInterpolator(factor));
objectAnimator1.setInterpolator(new DecelerateInterpolator(factor));
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(ANIMATION_DURATION);
animatorSet.playTogether(objectAnimator, objectAnimator1, scaleIndication);
animatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
freeFall();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animatorSet.start();
}
public float factor = 1.2f;
@SuppressLint("NewApi")
public void freeFall() {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mShapeLoadingView, "translationY", 0, mDistance);
ObjectAnimator scaleIndication = ObjectAnimator.ofFloat(mIndicationIm, "scaleX", 1, 0.2f);
objectAnimator.setDuration(ANIMATION_DURATION);
objectAnimator.setInterpolator(new AccelerateInterpolator(factor));
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(ANIMATION_DURATION);
animatorSet.playTogether(objectAnimator, scaleIndication);
animatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
mShapeLoadingView.changeShape();
upThrow();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animatorSet.start();
}
}
(2)ShapeLoadingView
package com.example.copy58loadingdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
public class ShapeLoadingView extends View {
private static final float genhao3 = 1.7320508075689f;
private static final float mTriangle2Circle =0.25555555f;
private Shape mShape = Shape.SHAPE_CIRCLE;
/**
* 用赛贝尔曲线画圆
*/
private float mMagicNumber = 0.55228475f;
public ShapeLoadingView(Context context) {
super(context);
init();
}
public ShapeLoadingView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ShapeLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// @TargetApi(Build.VERSION_CODES.LOLLIPOP)
// public ShapeLoadingView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
// super(context, attrs, defStyleAttr, defStyleRes);
// init();
// }
private void init() {
mPaint = new Paint();
mPaint.setColor(getResources().getColor(R.color.triangle));
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
setBackgroundColor(getResources().getColor(R.color.view_bg));
}
public boolean mIsLoading = false;
private Paint mPaint;
private float mControlX = 0;
private float mControlY = 0;
private float mAnimPercent;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(getVisibility()==GONE){
return;
}
// FIXME: 15/6/15 动画待优化
switch (mShape) {
case SHAPE_TRIANGLE:
if (mIsLoading) {
mAnimPercent += 0.1611113;
// triangle to circle
Path path = new Path();
path.moveTo(relativeXFromView(0.5f), relativeYFromView(0f));
if (mAnimPercent >= 1) {
mShape = Shape.SHAPE_CIRCLE;
mIsLoading = false;
mAnimPercent=1;
}
float controlX = mControlX - relativeXFromView(mAnimPercent* mTriangle2Circle)
* genhao3;
float controlY = mControlY - relativeYFromView(mAnimPercent* mTriangle2Circle);
path.quadTo(relativeXFromView(1) - controlX, controlY, relativeXFromView(0.5f + genhao3 / 4), relativeYFromView(0.75f));
path.quadTo(relativeXFromView(0.5f), relativeYFromView(0.75f + 2 * mAnimPercent* mTriangle2Circle), relativeXFromView(0.5f - genhao3 / 4), relativeYFromView(0.75f));
path.quadTo(controlX, controlY, relativeXFromView(0.5f), relativeYFromView(0f));
path.close();
canvas.drawPath(path, mPaint);
invalidate();
} else {
Path path = new Path();
mPaint.setColor(getResources().getColor(R.color.triangle));
path.moveTo(relativeXFromView(0.5f), relativeYFromView(0f));
path.lineTo(relativeXFromView(1), relativeYFromView(genhao3 / 2f));
path.lineTo(relativeXFromView(0), relativeYFromView(genhao3/2f));
mControlX = relativeXFromView(0.5f - genhao3 / 8.0f);
mControlY = relativeYFromView(3 / 8.0f);
mAnimPercent = 0;
path.close();
canvas.drawPath(path, mPaint);
}
break;
case SHAPE_CIRCLE:
if (mIsLoading) {
float magicNumber = mMagicNumber + mAnimPercent;
mAnimPercent += 0.12;
if (magicNumber + mAnimPercent >= 1.9f) {
mShape = Shape.SHAPE_RECT;
mIsLoading = false;
}
Path path = new Path();
path.moveTo(relativeXFromView(0.5f), relativeYFromView(0f));
path.cubicTo(relativeXFromView(0.5f + magicNumber / 2), relativeYFromView(0f),
relativeXFromView(1), relativeYFromView(0.5f - magicNumber / 2),
relativeXFromView(1f), relativeYFromView(0.5f));
path.cubicTo(
relativeXFromView(1), relativeXFromView(0.5f + magicNumber / 2),
relativeXFromView(0.5f + magicNumber / 2), relativeYFromView(1f),
relativeXFromView(0.5f), relativeYFromView(1f));
path.cubicTo(relativeXFromView(0.5f - magicNumber / 2), relativeXFromView(1f),
relativeXFromView(0), relativeYFromView(0.5f + magicNumber / 2),
relativeXFromView(0f), relativeYFromView(0.5f));
path.cubicTo(relativeXFromView(0f), relativeXFromView(0.5f - magicNumber / 2),
relativeXFromView(0.5f - magicNumber / 2), relativeYFromView(0),
relativeXFromView(0.5f), relativeYFromView(0f));
path.close();
canvas.drawPath(path, mPaint);
invalidate();
} else {
mPaint.setColor(getResources().getColor(R.color.circle));
Path path = new Path();
float magicNumber = mMagicNumber;
path.moveTo(relativeXFromView(0.5f), relativeYFromView(0f));
path.cubicTo(relativeXFromView(0.5f + magicNumber / 2), 0,
relativeXFromView(1), relativeYFromView(magicNumber / 2),
relativeXFromView(1f), relativeYFromView(0.5f));
path.cubicTo(
relativeXFromView(1), relativeXFromView(0.5f + magicNumber / 2),
relativeXFromView(0.5f + magicNumber / 2), relativeYFromView(1f),
relativeXFromView(0.5f), relativeYFromView(1f));
path.cubicTo(relativeXFromView(0.5f - magicNumber / 2), relativeXFromView(1f),
relativeXFromView(0), relativeYFromView(0.5f + magicNumber / 2),
relativeXFromView(0f), relativeYFromView(0.5f));
path.cubicTo(relativeXFromView(0f), relativeXFromView(0.5f - magicNumber / 2),
relativeXFromView(0.5f - magicNumber / 2), relativeYFromView(0),
relativeXFromView(0.5f), relativeYFromView(0f));
mAnimPercent = 0;
path.close();
canvas.drawPath(path, mPaint);
}
break;
case SHAPE_RECT:
if (mIsLoading) {
mAnimPercent += 0.15;
if (mAnimPercent >= 1) {
mShape = Shape.SHAPE_TRIANGLE;
mIsLoading = false;
mAnimPercent = 1;
}
Path path = new Path();
path.moveTo(relativeXFromView(0.5f * mAnimPercent), 0);
path.lineTo(relativeYFromView(1 - 0.5f * mAnimPercent), 0);
float distanceX = (mControlX) * mAnimPercent;
float distanceY = (relativeYFromView(1f) - mControlY) * mAnimPercent;
path.lineTo(relativeXFromView(1f) - distanceX, relativeYFromView(1f) - distanceY);
path.lineTo(relativeXFromView(0f) + distanceX, relativeYFromView(1f) - distanceY);
path.close();
canvas.drawPath(path, mPaint);
invalidate();
} else {
mPaint.setColor(getResources().getColor(R.color.rect));
mControlX = relativeXFromView(0.5f - genhao3 / 4);
mControlY = relativeYFromView(0.75f);
Path path = new Path();
path.moveTo(relativeXFromView(0f), relativeYFromView(0f));
path.lineTo(relativeXFromView(1f), relativeYFromView(0f));
path.lineTo(relativeXFromView(1f), relativeYFromView(1f));
path.lineTo(relativeXFromView(0f), relativeYFromView(1f));
path.close();
mAnimPercent = 0;
canvas.drawPath(path, mPaint);
}
break;
}
}
private float relativeXFromView(float percent) {
return getWidth() * percent;
}
private float relativeYFromView(float percent) {
return getHeight() * percent;
}
public void changeShape() {
mIsLoading = true;
invalidate();
}
public enum Shape {
SHAPE_TRIANGLE, SHAPE_RECT, SHAPE_CIRCLE
}
@Override
public void setVisibility(int visibility) {
super.setVisibility(visibility);
if(visibility==VISIBLE){
invalidate();
}
}
public Shape getShape() {
return mShape;
}
}
(3)ParamsCreator
package com.example.copy58loadingdemo;
import android.content.Context;
import android.util.DisplayMetrics;
import android.view.WindowManager;
public class ParamsCreator {
private Context context;
private int screenWidth;//屏幕宽度
private int screenHeight;//屏幕高度
private int densityDpi;//像素密度
public ParamsCreator(Context context){
this.context = context;
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
screenWidth = wm.getDefaultDisplay().getWidth();
screenHeight = wm.getDefaultDisplay().getHeight();
DisplayMetrics metric = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metric);
densityDpi = metric.densityDpi;
}
/**
* 获得默认圆的半径
*/
public int getDefaultCircleRadius(){
if(screenWidth >= 1400){//1440
return 40;
}
if(screenWidth >= 1000){//1080
if(densityDpi >=480)
return 38;
if(densityDpi >= 320)
return 38;
return 38;
}
if(screenWidth >= 700){//720
if(densityDpi >= 320)
return 24;
if(densityDpi >= 240)
return 24;
if(densityDpi >= 160)
return 24;
return 24;
}
if(screenWidth >= 500){//540
if(densityDpi >= 320)
return 20;
if(densityDpi >= 240)
return 20;
if(densityDpi >= 160)
return 20;
return 20;
}
return 20;
}
/**
* 获得默认圆的间距
*/
public int getDefaultCircleSpacing(){
if(screenWidth >= 1400){//1440
return 10;
}
if(screenWidth >= 1000){//1080
if(densityDpi >=480)
return 10;
if(densityDpi >= 320)
return 10;
return 10;
}
if(screenWidth >= 700){//720
if(densityDpi >= 320)
return 6;
if(densityDpi >= 240)
return 6;
if(densityDpi >= 160)
return 6;
return 6;
}
if(screenWidth >= 500){//540
if(densityDpi >= 320)
return 3;
if(densityDpi >= 240)
return 3;
if(densityDpi >= 160)
return 3;
return 3;
}
return 3;
}
}
(4)MonIndicator
package com.example.copy58loadingdemo;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
public class MonIndicator extends View{
private ParamsCreator paramsCreator = new ParamsCreator(this.getContext());
private List<CircleWrapper> wrappers;
private int[] colors = new int[]{0xFF942909, 0xFF577B8C, 0xFF201289, 0xFF7E207C, 0xFF38B549};
private Paint paint = new Paint();
private RectF oval=new RectF();
//属性
private int circleRadius;//圆半径
private int circleSpacing;//圆间距
private int increment = 2;//增量
public MonIndicator(Context context) {
super(context);
}
public MonIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.monindicator);
circleRadius = (int)a.getDimension(R.styleable.monindicator_circleRadius, paramsCreator.getDefaultCircleRadius());
circleSpacing = (int)a.getDimension(R.styleable.monindicator_circleSpacing, paramsCreator.getDefaultCircleSpacing());
int cycle = a.getInt(R.styleable.monindicator_cycle, 1500);//周期,默认为1.5秒
cycle = cycle/2;
int number = (int)(cycle*1.0/1000 * 83);
this.increment = (int)(this.circleRadius * 2.0 / number);
this.increment = this.increment<=0?1:this.increment;
createWrappers();
}
/**
* 创建wrappers
*/
private void createWrappers(){
wrappers = new ArrayList<CircleWrapper>();
int diameter = this.circleRadius * 1;//直径
//第一个圆
CircleWrapper wrapper = new CircleWrapper();
wrapper.diameter = diameter;
wrapper.initDiameter = diameter;
wrapper.dynamicDiameter = wrapper.initDiameter;
wrapper.orientation = -1;
wrappers.add(wrapper);
//第二个圆
wrapper = new CircleWrapper();
wrapper.diameter = diameter;
wrapper.initDiameter = (int)(diameter*0.75);
wrapper.dynamicDiameter = wrapper.initDiameter;
wrapper.orientation = 1;
wrappers.add(wrapper);
//第三个圆
wrapper = new CircleWrapper();
wrapper.diameter = diameter;
wrapper.initDiameter = (int)(diameter*0.5);
wrapper.dynamicDiameter = wrapper.initDiameter;
wrapper.orientation = 1;
wrappers.add(wrapper);
//第四个圆
wrapper = new CircleWrapper();
wrapper.diameter = diameter;
wrapper.initDiameter = (int)(diameter*0.25);
wrapper.dynamicDiameter = wrapper.initDiameter;
wrapper.orientation = 1;
wrappers.add(wrapper);
//第五个圆
wrapper = new CircleWrapper();
wrapper.diameter = diameter;
wrapper.initDiameter = 0;
wrapper.dynamicDiameter = 0;
wrapper.orientation = 1;
wrappers.add(wrapper);
}
/**
* 测绘
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
}
/**
* 计算组件宽度
*/
private int measureWidth(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
result = getDefaultWidth();
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
/**
* 计算组件高度
*/
private int measureHeight(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
result = getDefaultHeight();
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
/**
* 计算默认宽度
*/
private int getDefaultWidth(){
int defaultWidth = this.circleRadius * 2 * this.wrappers.size() + (this.wrappers.size()-1) * this.circleSpacing;
return defaultWidth;
}
/**
* 计算默认宽度
*/
private int getDefaultHeight(){
return this.circleRadius * 2;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
//canvas.drawColor(0xFF00FF33);
drawCircle01(canvas);
drawCircle02(canvas);
drawCircle03(canvas);
drawCircle04(canvas);
drawCircle05(canvas);
this.invalidate();
}
/**
* 画圆1
*/
private void drawCircle01(Canvas canvas){
paint.setColor(colors[0]);
CircleWrapper wrapper = wrappers.get(0);
wrapper.dynamicDiameter = wrapper.dynamicDiameter + wrapper.orientation * this.increment;
if(wrapper.dynamicDiameter >= wrapper.diameter){
wrapper.orientation = -1;
wrapper.dynamicDiameter = wrapper.diameter;
}
if(wrapper.dynamicDiameter <= 0){
wrapper.orientation = 1;
wrapper.dynamicDiameter = 0;
}
int totalWidth = this.circleRadius * 2 * this.wrappers.size() + (this.wrappers.size()-1) * this.circleSpacing;
int centerX = this.getWidth()/2 - totalWidth/2 + this.circleRadius;
int centerY = this.getHeight()/2;
oval.left = centerX - wrapper.dynamicDiameter/2 ;
oval.top = centerY - wrapper.dynamicDiameter/2;
oval.right = oval.left + wrapper.dynamicDiameter;
oval.bottom = oval.top + wrapper.dynamicDiameter;
canvas.drawArc(oval, 0, 360, false, paint);
}
/**
* 画圆2
*/
private void drawCircle02(Canvas canvas){
paint.setColor(colors[1]);
CircleWrapper wrapper = wrappers.get(1);
CircleWrapper wrapper01 = wrappers.get(0);
if(wrapper01.dynamicDiameter == wrapper01.initDiameter){
wrapper.dynamicDiameter = wrapper.initDiameter;
}else{
wrapper.dynamicDiameter = wrapper.dynamicDiameter + wrapper.orientation * this.increment;
if(wrapper.dynamicDiameter >= wrapper.diameter){
wrapper.orientation = -1;
wrapper.dynamicDiameter = wrapper.diameter;
}
if(wrapper.dynamicDiameter <= 0){
wrapper.orientation = 1;
wrapper.dynamicDiameter = 0;
}
}
int totalWidth = this.circleRadius * 2 * this.wrappers.size() + (this.wrappers.size()-1) * this.circleSpacing;
int centerX = this.getWidth()/2 - totalWidth/2 + (wrapper.diameter + this.circleSpacing) * 1 + this.circleRadius;
int centerY = this.getHeight()/2;
oval.left = centerX - wrapper.dynamicDiameter/2 ;
oval.top = centerY - wrapper.dynamicDiameter/2;
oval.right = oval.left + wrapper.dynamicDiameter;
oval.bottom = oval.top + wrapper.dynamicDiameter;
canvas.drawArc(oval, 0, 360, false, paint);
}
/**
* 画圆3
*/
private void drawCircle03(Canvas canvas){
paint.setColor(colors[2]);
CircleWrapper wrapper = wrappers.get(2);
CircleWrapper wrapper01 = wrappers.get(0);
if(wrapper01.dynamicDiameter == wrapper01.initDiameter){
wrapper.dynamicDiameter = wrapper.initDiameter;
}else{
wrapper.dynamicDiameter = wrapper.dynamicDiameter + wrapper.orientation * this.increment;
if(wrapper.dynamicDiameter >= wrapper.diameter){
wrapper.orientation = -1;
wrapper.dynamicDiameter = wrapper.diameter;
}
if(wrapper.dynamicDiameter <= 0){
wrapper.orientation = 1;
wrapper.dynamicDiameter = 0;
}
}
int totalWidth = this.circleRadius * 2 * this.wrappers.size() + (this.wrappers.size()-1) * this.circleSpacing;
int centerX = this.getWidth()/2 - totalWidth/2 + (wrapper.diameter + this.circleSpacing) * 2 + this.circleRadius;
int centerY = this.getHeight()/2;
oval.left = centerX - wrapper.dynamicDiameter/2 ;
oval.top = centerY - wrapper.dynamicDiameter/2;
oval.right = oval.left + wrapper.dynamicDiameter;
oval.bottom = oval.top + wrapper.dynamicDiameter;
canvas.drawArc(oval, 0, 360, false, paint);
}
/**
* 画圆4
*/
private void drawCircle04(Canvas canvas){
paint.setColor(colors[3]);
CircleWrapper wrapper = wrappers.get(3);
CircleWrapper wrapper01 = wrappers.get(0);
if(wrapper01.dynamicDiameter == wrapper01.initDiameter){
wrapper.dynamicDiameter = wrapper.initDiameter;
}else{
wrapper.dynamicDiameter = wrapper.dynamicDiameter + wrapper.orientation * this.increment;
if(wrapper.dynamicDiameter >= wrapper.diameter){
wrapper.orientation = -1;
wrapper.dynamicDiameter = wrapper.diameter;
}
if(wrapper.dynamicDiameter <= 0){
wrapper.orientation = 1;
wrapper.dynamicDiameter = 0;
}
}
int totalWidth = this.circleRadius * 2 * this.wrappers.size() + (this.wrappers.size()-1) * this.circleSpacing;
int centerX = this.getWidth()/2 - totalWidth/2 + (wrapper.diameter + this.circleSpacing) * 3 + this.circleRadius;
int centerY = this.getHeight()/2;
oval.left = centerX - wrapper.dynamicDiameter/2 ;
oval.top = centerY - wrapper.dynamicDiameter/2;
oval.right = oval.left + wrapper.dynamicDiameter;
oval.bottom = oval.top + wrapper.dynamicDiameter;
canvas.drawArc(oval, 0, 360, false, paint);
}
/**
* 画圆5
*/
private void drawCircle05(Canvas canvas){
paint.setColor(colors[4]);
CircleWrapper wrapper = wrappers.get(4);
CircleWrapper wrapper01 = wrappers.get(0);
wrapper.dynamicDiameter = wrapper.diameter - wrapper01.dynamicDiameter;
int totalWidth = this.circleRadius * 2 * this.wrappers.size() + (this.wrappers.size()-1) * this.circleSpacing;
int centerX = this.getWidth()/2 - totalWidth/2 + (wrapper.diameter + this.circleSpacing) * 4 + this.circleRadius;
int centerY = this.getHeight()/2;
oval.left = centerX - wrapper.dynamicDiameter/2 ;
oval.top = centerY - wrapper.dynamicDiameter/2;
oval.right = oval.left + wrapper.dynamicDiameter;
oval.bottom = oval.top + wrapper.dynamicDiameter;
canvas.drawArc(oval, 0, 360, false, paint);
}
/**
* 设置颜色
* @param colors
*/
public void setColors(int[] colors) {
if(colors == null || colors.length == 0)
return ;
for(int i = 0; i<colors.length&&i<this.colors.length; i++){
this.colors[i] = colors[i];
}
}
/**
* 内部类
*/
private class CircleWrapper{
private int diameter;//圆的直径
private int initDiameter;//初始直径
private int dynamicDiameter;//动态直径
private int orientation;//方向,即增加还是减少 1:增加 -1为减少
}
}