先上效果图
我将其分为模型层和View层模型层有4个类,Arc弧,Circle圆 Line线,他们都继承GraphicObject类,抽取他们公有属性(需要Paint来Draw)作为抽象基类。所以GraphicObject有Paint成员和抽象Draw(Canvas)方法。Arc就利用Canvas.DrawArc方法来绘制弧,Circle利用Canvas.DrawCircle方法绘制小圆,Line利用Canvas.DrawLine方法绘制线 View层利用模型层这些基础绘制相应的view。 View层基类为LoaderView,源码如下:初始化监听接口,宽高,中心点成员 protected int color; protected int width, height; protected int desiredWidth, desiredHeight; protected PointF center; protected InvalidateListener invalidateListener;
public LoaderView() { this.desiredWidth = 150; this.desiredHeight = 150; }
public void setColor(int color) { this.color = color; }
public void setSize(int width, int height) { this.width = width; this.height = height; this.center = new PointF(width / 2.0f, height / 2.0f); }
public void setInvalidateListener(InvalidateListener invalidateListener) { this.invalidateListener = invalidateListener; }
public int getDesiredWidth() { return desiredWidth; }
public int getDesiredHeight() { return desiredHeight; }
public abstract void initializeObjects();
public abstract void setUpAnimation();
public abstract void draw(Canvas canvas); 以所传的画布左上角为坐标原点,坐标轴和屏幕坐标轴一致,也是向下向右型。所以作为中心点的直接设置为宽高的一半。 ClassicSpinner经典进度条 通过在draw方法围绕中心点旋转和设置每个小圆的间隔透明动画来实现动画效果,主要代码如下: @Override public void setUpAnimation() { for (int i = 0; i < circlesSize; i++) { final int index = i;
ValueAnimator fadeAnimator = ValueAnimator.ofInt(126, 255, 126); fadeAnimator.setRepeatCount(ValueAnimator.INFINITE); fadeAnimator.setDuration(1000); fadeAnimator.setStartDelay(index * 120); fadeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { circles[index].setAlpha((int)animation.getAnimatedValue()); invalidateListener.reDraw(); } });
fadeAnimator.start(); } } @Override public void draw(Canvas canvas) { for (int i = 0; i < circlesSize; i++) { canvas.save(); canvas.rotate(45 * i, center.x, center.y); circles[i].draw(canvas); canvas.restore(); } 除了ClassicSpinner之外还有其他视图类,如FishSpinner,LineSpinner等,和ClassicSpinner类差不多。通过一个类似工厂的类LoaderGenerator来生成各种视图类对象。自定义一个MKLoader继承View类通过属性设置参数不同,LoaderGenerator能生成不同视图类对象,做到一个自定义View能根据需求显示不同的View。 动画仅仅通过ValueAnimator延迟变化设置值结合CanvasDraw方法搞出绚丽的界面。我是十分佩服的。 最后附上开源地址 https://github.com/nntuyen/mkloader.git 祝该开源项目搞得越来越好。
|