diff --git a/.gitignore b/.gitignore
index a881469..e479603 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@
.DS_Store
/build
/captures
+*.iml
\ No newline at end of file
diff --git a/LoadingDrawable.iml b/LoadingDrawable.iml
deleted file mode 100644
index eb791b2..0000000
--- a/LoadingDrawable.iml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Preview/CircleJumpDrawable.gif b/Preview/CircleJumpDrawable.gif
index 5345ad6..58af668 100644
Binary files a/Preview/CircleJumpDrawable.gif and b/Preview/CircleJumpDrawable.gif differ
diff --git a/README-ZH.md b/README-ZH.md
deleted file mode 100644
index 26cd368..0000000
--- a/README-ZH.md
+++ /dev/null
@@ -1,94 +0,0 @@
-
-## LoadingDrawable
-[](http://android-arsenal.com/details/1/3450)
-
- 一些酷炫的加载动画, 可以与任何View配合使用,作为加载动画或者Progressbar, 此外很适合与[RecyclerRefreshLayout](https://github.com/dinuscxj/RecyclerRefreshLayout)
- 配合使用作为刷新的loading 动画
-
- 这个项目的思路源于这个动画链接 [link] (http://mp.weixin.qq.com/s?__biz=MjM5MDMxOTE5NA==&mid=402703079&idx=2&sn=2fcc6746a866dcc003c68ead9b68e595&scene=2&srcid=0302A7p723KK8E5gSzLKb2ZL&from=timeline&isappinstalled=0#wechat_redirect).
- 或许你更喜欢使用Gif实现 : [GifLoadingView] (https://github.com/Rogero0o/GifLoadingView).
-
-
-
-
-
-
-
-
-## 功能
-
-#### 形变系列
- * CircleBroodLoadingRenderer
- * CoolWaitLoadingRenderer
-
-#### 物品系列
- * BalloonLoadingRenderer
- * WaterBottleLoadingRenderer
-
-#### 动物系列
- * FishLoadingRenderer
- * GhostsEyeLoadingRenderer
-
-#### 风景系列
- * DayNightLoadingRenderer
- * ElectricFanLoadingRenderer
-
-#### 圆形滚动系列
- * GearLoadingRenderer
- * WhorlLoadingRenderer
- * LevelLoadingRenderer
- * MaterialLoadingRenderer
-
-#### 圆形跳动系列
- * SwapLoadingRenderer
- * GuardLoadingRenderer
- * DanceLoadingRenderer
- * CollisionLoadingRenderer
-
-## 待办事项
-当我感觉bug比较少的时候,我会添加一个gradle依赖。 所以在推上去之前希望大家多提提建议和bug.
-
-## 用法
-#### Gradle
- ```
- compile project(':library')
- ```
-#### 在代码里
-
- ```java
- LoadingView.setLoadingRenderer(LoadingRenderer);
- ```
-
-#### 在xml中
- ```xml
-
- ```
-
-如果LoadingView不能满足你的需求,或许你需要参考LoadingView进行自定义View
-
-## 杂谈
-如果你喜欢LoadingDrawable或者在使用它, 你可以
-
- * star这个项目
- * 提一些建议, 谢谢。
-
-## License
- Copyright 2015-2019 dinus
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/README.md b/README.md
index 528b43c..b3a0868 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,24 @@
## LoadingDrawable: Android cool animation collection
-[中文版文档](https://github.com/dinuscxj/LoadingDrawable/blob/master/README-ZH.md)
[前言](http://www.jianshu.com/p/6e0ac5af4e8b)
-[Circle系列源码解析](http://www.jianshu.com/p/1c3c6fc1b7ff)
+[CircleRotate源码解析](http://www.jianshu.com/p/1c3c6fc1b7ff)
[Fish源码解析](http://blog.csdn.net/XSF50717/article/details/51494266)
[](http://android-arsenal.com/details/1/3450)
- Some android loading drawable, can be combined with any View as the loading View and Progressbar,
-
- This project idea is from the [link] (http://mp.weixin.qq.com/s?__biz=MjM5MDMxOTE5NA==&mid=402703079&idx=2&sn=2fcc6746a866dcc003c68ead9b68e595&scene=2&srcid=0302A7p723KK8E5gSzLKb2ZL&from=timeline&isappinstalled=0#wechat_redirect).
- Perhaps you prefer to use gif way to achieve : [GifLoadingView] (https://github.com/Rogero0o/GifLoadingView).
+ LoadingDrawable is some android animations implement of drawable: a library can be used in the pull-down to refresh, the placeholders of image loading and the time-consuming tasks. This project idea is from the [link](http://mp.weixin.qq.com/s?__biz=MjM5MDMxOTE5NA==&mid=402703079&idx=2&sn=2fcc6746a866dcc003c68ead9b68e595&scene=2&srcid=0302A7p723KK8E5gSzLKb2ZL&from=timeline&isappinstalled=0#wechat_redirect).
+
+The following content show a brief overview of LoadingDrawable
+
+* It extends `Drawable` and implement the interface `Animatable`
+* it uses strategy mode
+* It can be used as the background of View or content of `ImageView`
+* It's constructor must be passed a `LoadingRenderer`
+* It interact with `LoadingRenderer` by the callback `Callback`
+* `LoadingRenderer` is used for measuring and drawing the `LoadingDrawable`. note:
+`LoadingRenderer` is the core
+* `LoadingRenderer` only can be created by their `Builder`.
+
+Learn more about LoadingDrawable on the [Wiki Home](https://github.com/dinuscxj/LoadingDrawable/wiki).


@@ -18,7 +27,7 @@


-## Features
+## LoadingRenderer Style
#### ShapeChange
* CircleBroodLoadingRenderer
@@ -33,37 +42,23 @@
* GhostsEyeLoadingEyeRenderer
#### Scenery
- * DayNightLoadingRenderer
* ElectricFanLoadingRenderer
-
-#### Circle Rotate
- * GearLoadingRenderer
- * WhorlLoadingRenderer
- * LevelLoadingRenderer
- * MaterialLoadingRenderer
+ * DayNightLoadingRenderer
#### Circle Jump
+ * CollisionLoadingRenderer
* SwapLoadingRenderer
* GuardLoadingRenderer
* DanceLoadingRenderer
- * CollisionLoadingRenderer
-## TODO
- When I feel less bugs enough, I will add a gradle dependency. So I hope you will make more Suggestions or Issues.
+#### Circle Rotate
+ * WhorlLoadingRenderer
+ * MaterialLoadingRenderer
+ * GearLoadingRenderer
+ * LevelLoadingRenderer
## Usage
-#### Gradle
- ```
- compile project(':library')
- ```
-#### In java
-
- ```java
- LoadingView.setLoadingRenderer(LoadingRenderer);
- ```
-
-#### In xml
-
+ Define the `LoadingView` in XML and specify the `LoadingRenderer` style:
```xml
```
-
-If the LoadingView can't meet your requirements, you might need to refer to the LoadingView customize the View you need
+ Or specify the `LoadingRenderer` style in Java
+ ```java
+ ***LoadingRenderer.Builder builder = new ***LoadingRenderer.Builder(context);
+ LoadingView.setLoadingRenderer(builder.build());
+ ```
+
+## TODO
+ When I feel less bugs enough, I will add a gradle dependency. So I hope you will make more Suggestions or Issues.
## Misc
If you like LoadingDrawable or use it, could you please:
* star this repo
* send me some feedback. Thanks!
+
+ ***QQ Group:*** **342748245**
## License
Copyright 2015-2019 dinus
diff --git a/app/app.iml b/app/app.iml
deleted file mode 100644
index c8d9349..0000000
--- a/app/app.iml
+++ /dev/null
@@ -1,120 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- generateDebugSources
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/java/app/dinus/com/example/AnimalActivity.java b/app/src/main/java/app/dinus/com/example/AnimalActivity.java
index fde72d1..45c1bee 100644
--- a/app/src/main/java/app/dinus/com/example/AnimalActivity.java
+++ b/app/src/main/java/app/dinus/com/example/AnimalActivity.java
@@ -4,11 +4,6 @@
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
-import android.widget.ImageView;
-
-import app.dinus.com.loadingdrawable.LoadingDrawable;
-import app.dinus.com.loadingdrawable.render.animal.FishLoadingRenderer;
-import app.dinus.com.loadingdrawable.render.animal.GhostsEyeLoadingRenderer;
public class AnimalActivity extends AppCompatActivity {
public static void startActivity(Context context) {
diff --git a/app/src/main/java/app/dinus/com/example/CircleJumpActivity.java b/app/src/main/java/app/dinus/com/example/CircleJumpActivity.java
index 313c0a2..bf95c98 100644
--- a/app/src/main/java/app/dinus/com/example/CircleJumpActivity.java
+++ b/app/src/main/java/app/dinus/com/example/CircleJumpActivity.java
@@ -4,13 +4,6 @@
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
-import android.widget.ImageView;
-
-import app.dinus.com.loadingdrawable.LoadingDrawable;
-import app.dinus.com.loadingdrawable.render.circle.jump.CollisionLoadingRenderer;
-import app.dinus.com.loadingdrawable.render.circle.jump.DanceLoadingRenderer;
-import app.dinus.com.loadingdrawable.render.circle.jump.GuardLoadingRenderer;
-import app.dinus.com.loadingdrawable.render.circle.jump.SwapLoadingRenderer;
public class CircleJumpActivity extends AppCompatActivity {
public static void startActivity(Context context) {
diff --git a/app/src/main/java/app/dinus/com/example/CircleRotateActivity.java b/app/src/main/java/app/dinus/com/example/CircleRotateActivity.java
index a4fdf8e..ffd562e 100644
--- a/app/src/main/java/app/dinus/com/example/CircleRotateActivity.java
+++ b/app/src/main/java/app/dinus/com/example/CircleRotateActivity.java
@@ -2,11 +2,13 @@
import android.content.Context;
import android.content.Intent;
+import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
-import android.widget.ImageView;
-import app.dinus.com.loadingdrawable.LoadingDrawable;
+import app.dinus.com.loadingdrawable.DensityUtil;
+import app.dinus.com.loadingdrawable.LoadingView;
+import app.dinus.com.loadingdrawable.render.LoadingRenderer;
import app.dinus.com.loadingdrawable.render.circle.rotate.GearLoadingRenderer;
import app.dinus.com.loadingdrawable.render.circle.rotate.LevelLoadingRenderer;
import app.dinus.com.loadingdrawable.render.circle.rotate.MaterialLoadingRenderer;
diff --git a/app/src/main/java/app/dinus/com/example/GoodsActivity.java b/app/src/main/java/app/dinus/com/example/GoodsActivity.java
index 1bfe40e..552b59f 100644
--- a/app/src/main/java/app/dinus/com/example/GoodsActivity.java
+++ b/app/src/main/java/app/dinus/com/example/GoodsActivity.java
@@ -4,12 +4,6 @@
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
-import android.widget.ImageView;
-
-import app.dinus.com.loadingdrawable.LoadingDrawable;
-import app.dinus.com.loadingdrawable.render.animal.GhostsEyeLoadingRenderer;
-import app.dinus.com.loadingdrawable.render.goods.BalloonLoadingRenderer;
-import app.dinus.com.loadingdrawable.render.goods.WaterBottleLoadingRenderer;
public class GoodsActivity extends AppCompatActivity {
diff --git a/app/src/main/java/app/dinus/com/example/SceneryActivity.java b/app/src/main/java/app/dinus/com/example/SceneryActivity.java
index 545c39f..b6756aa 100644
--- a/app/src/main/java/app/dinus/com/example/SceneryActivity.java
+++ b/app/src/main/java/app/dinus/com/example/SceneryActivity.java
@@ -4,11 +4,6 @@
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
-import android.widget.ImageView;
-
-import app.dinus.com.loadingdrawable.LoadingDrawable;
-import app.dinus.com.loadingdrawable.render.scenery.DayNightLoadingRenderer;
-import app.dinus.com.loadingdrawable.render.scenery.ElectricFanLoadingRenderer;
public class SceneryActivity extends AppCompatActivity {
diff --git a/app/src/main/java/app/dinus/com/example/ShapeChangeActivity.java b/app/src/main/java/app/dinus/com/example/ShapeChangeActivity.java
index a278d35..5cc5d83 100644
--- a/app/src/main/java/app/dinus/com/example/ShapeChangeActivity.java
+++ b/app/src/main/java/app/dinus/com/example/ShapeChangeActivity.java
@@ -4,11 +4,6 @@
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
-import android.widget.ImageView;
-
-import app.dinus.com.loadingdrawable.LoadingDrawable;
-import app.dinus.com.loadingdrawable.render.shapechange.CircleBroodLoadingRenderer;
-import app.dinus.com.loadingdrawable.render.shapechange.CoolWaitLoadingRenderer;
public class ShapeChangeActivity extends AppCompatActivity {
diff --git a/library/library.iml b/library/library.iml
deleted file mode 100644
index ed83241..0000000
--- a/library/library.iml
+++ /dev/null
@@ -1,110 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- generateDebugSources
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/LoadingView.java b/library/src/main/java/app/dinus/com/loadingdrawable/LoadingView.java
index d919880..ba77e64 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/LoadingView.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/LoadingView.java
@@ -6,6 +6,7 @@
import android.view.View;
import android.widget.ImageView;
+import app.dinus.com.loadingdrawable.render.LoadingDrawable;
import app.dinus.com.loadingdrawable.render.LoadingRenderer;
import app.dinus.com.loadingdrawable.render.LoadingRendererFactory;
@@ -53,7 +54,9 @@ protected void onDetachedFromWindow() {
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
- if (visibility == View.VISIBLE) {
+
+ final boolean visible = visibility == VISIBLE && getVisibility() == VISIBLE;
+ if (visible) {
startAnimation();
} else {
stopAnimation();
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/LoadingDrawable.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/LoadingDrawable.java
similarity index 68%
rename from library/src/main/java/app/dinus/com/loadingdrawable/LoadingDrawable.java
rename to library/src/main/java/app/dinus/com/loadingdrawable/render/LoadingDrawable.java
index e021df3..0c30ed6 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/LoadingDrawable.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/LoadingDrawable.java
@@ -1,15 +1,16 @@
-package app.dinus.com.loadingdrawable;
+package app.dinus.com.loadingdrawable.render;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
+import android.graphics.Rect;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import app.dinus.com.loadingdrawable.render.LoadingRenderer;
public class LoadingDrawable extends Drawable implements Animatable {
- private LoadingRenderer mLoadingRender;
+ private final LoadingRenderer mLoadingRender;
private final Callback mCallback = new Callback() {
@Override
@@ -33,19 +34,27 @@ public LoadingDrawable(LoadingRenderer loadingRender) {
this.mLoadingRender.setCallback(mCallback);
}
+ @Override
+ protected void onBoundsChange(Rect bounds) {
+ super.onBoundsChange(bounds);
+ this.mLoadingRender.setBounds(bounds);
+ }
+
@Override
public void draw(Canvas canvas) {
- mLoadingRender.draw(canvas, getBounds());
+ if (!getBounds().isEmpty()) {
+ this.mLoadingRender.draw(canvas);
+ }
}
@Override
public void setAlpha(int alpha) {
- mLoadingRender.setAlpha(alpha);
+ this.mLoadingRender.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
- mLoadingRender.setColorFilter(cf);
+ this.mLoadingRender.setColorFilter(cf);
}
@Override
@@ -55,26 +64,26 @@ public int getOpacity() {
@Override
public void start() {
- mLoadingRender.start();
+ this.mLoadingRender.start();
}
@Override
public void stop() {
- mLoadingRender.stop();
+ this.mLoadingRender.stop();
}
@Override
public boolean isRunning() {
- return mLoadingRender.isRunning();
+ return this.mLoadingRender.isRunning();
}
@Override
public int getIntrinsicHeight() {
- return (int) mLoadingRender.getHeight();
+ return (int) this.mLoadingRender.mHeight;
}
@Override
public int getIntrinsicWidth() {
- return (int) mLoadingRender.getWidth();
+ return (int) this.mLoadingRender.mWidth;
}
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/LoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/LoadingRenderer.java
index d74efe4..fe0282b 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/LoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/LoadingRenderer.java
@@ -6,10 +6,12 @@
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.drawable.Drawable;
-import android.util.DisplayMetrics;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
import android.view.animation.Animation;
-import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import app.dinus.com.loadingdrawable.DensityUtil;
@@ -18,51 +20,87 @@ public abstract class LoadingRenderer {
private static final long ANIMATION_DURATION = 1333;
private static final float DEFAULT_SIZE = 56.0f;
- protected float mWidth;
- protected float mHeight;
+ private final ValueAnimator.AnimatorUpdateListener mAnimatorUpdateListener
+ = new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ computeRender((float) animation.getAnimatedValue());
+ invalidateSelf();
+ }
+ };
+
+ /**
+ * Whenever {@link LoadingDrawable} boundary changes mBounds will be updated.
+ * More details you can see {@link LoadingDrawable#onBoundsChange(Rect)}
+ */
+ protected final Rect mBounds = new Rect();
- private long mDuration;
private Drawable.Callback mCallback;
private ValueAnimator mRenderAnimator;
+ protected long mDuration;
+
+ protected float mWidth;
+ protected float mHeight;
+
public LoadingRenderer(Context context) {
- setupDefaultParams(context);
+ initParams(context);
setupAnimators();
}
- public abstract void draw(Canvas canvas, Rect bounds);
+ @Deprecated
+ protected void draw(Canvas canvas, Rect bounds) {
+ }
+
+ protected void draw(Canvas canvas) {
+ draw(canvas, mBounds);
+ }
- public abstract void computeRender(float renderProgress);
+ protected abstract void computeRender(float renderProgress);
- public abstract void setAlpha(int alpha);
+ protected abstract void setAlpha(int alpha);
- public abstract void setColorFilter(ColorFilter cf);
+ protected abstract void setColorFilter(ColorFilter cf);
- public abstract void reset();
+ protected abstract void reset();
- public void start() {
+ protected void addRenderListener(Animator.AnimatorListener animatorListener) {
+ mRenderAnimator.addListener(animatorListener);
+ }
+
+ void start() {
reset();
- setDuration(mDuration);
+ mRenderAnimator.addUpdateListener(mAnimatorUpdateListener);
+
+ mRenderAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ mRenderAnimator.setDuration(mDuration);
mRenderAnimator.start();
}
- public void stop() {
- mRenderAnimator.cancel();
+ void stop() {
+ // if I just call mRenderAnimator.end(),
+ // it will always call the method onAnimationUpdate(ValueAnimator animation)
+ // why ? if you know why please send email to me (dinus_developer@163.com)
+ mRenderAnimator.removeUpdateListener(mAnimatorUpdateListener);
+
+ mRenderAnimator.setRepeatCount(0);
+ mRenderAnimator.setDuration(0);
+ mRenderAnimator.end();
}
- public boolean isRunning() {
+ boolean isRunning() {
return mRenderAnimator.isRunning();
}
- public void setCallback(Drawable.Callback callback) {
+ void setCallback(Drawable.Callback callback) {
this.mCallback = callback;
}
- protected void invalidateSelf() {
- mCallback.invalidateDrawable(null);
+ void setBounds(Rect bounds) {
+ mBounds.set(bounds);
}
- private void setupDefaultParams(Context context) {
+ private void initParams(Context context) {
mWidth = DensityUtil.dip2px(context, DEFAULT_SIZE);
mHeight = DensityUtil.dip2px(context, DEFAULT_SIZE);
@@ -73,44 +111,14 @@ private void setupAnimators() {
mRenderAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
mRenderAnimator.setRepeatCount(Animation.INFINITE);
mRenderAnimator.setRepeatMode(Animation.RESTART);
+ mRenderAnimator.setDuration(mDuration);
//fuck you! the default interpolator is AccelerateDecelerateInterpolator
mRenderAnimator.setInterpolator(new LinearInterpolator());
- mRenderAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- computeRender((float) animation.getAnimatedValue());
- invalidateSelf();
- }
- });
-
+ mRenderAnimator.addUpdateListener(mAnimatorUpdateListener);
}
- protected void addRenderListener(Animator.AnimatorListener animatorListener) {
- mRenderAnimator.addListener(animatorListener);
- }
-
- public float getWidth() {
- return mWidth;
- }
-
- public void setWidth(float width) {
- this.mWidth = width;
- }
-
- public float getHeight() {
- return mHeight;
- }
-
- public void setHeight(float height) {
- this.mHeight = height;
- }
-
- public long getDuration() {
- return mDuration;
+ private void invalidateSelf() {
+ mCallback.invalidateDrawable(null);
}
- public void setDuration(long duration) {
- this.mDuration = duration;
- mRenderAnimator.setDuration(mDuration);
- }
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/LoadingRendererFactory.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/LoadingRendererFactory.java
index 45227db..59040b0 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/LoadingRendererFactory.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/LoadingRendererFactory.java
@@ -61,6 +61,7 @@ public static LoadingRenderer createLoadingRenderer(Context context, int loading
if (parameterTypes != null
&& parameterTypes.length == 1
&& parameterTypes[0].equals(Context.class)) {
+ constructor.setAccessible(true);
return (LoadingRenderer) constructor.newInstance(context);
}
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/animal/FishLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/animal/FishLoadingRenderer.java
index 7c6f63d..2c63d48 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/animal/FishLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/animal/FishLoadingRenderer.java
@@ -70,7 +70,7 @@ public class FishLoadingRenderer extends LoadingRenderer {
private int mColor;
- public FishLoadingRenderer(Context context) {
+ private FishLoadingRenderer(Context context) {
super(context);
init(context);
setupPaint();
@@ -91,7 +91,7 @@ private void init(Context context) {
mColor = DEFAULT_COLOR;
- setDuration(ANIMATION_DURATION);
+ mDuration = ANIMATION_DURATION;
}
private void setupPaint() {
@@ -103,7 +103,7 @@ private void setupPaint() {
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas, Rect bounds) {
int saveCount = canvas.save();
RectF arcBounds = mTempBounds;
arcBounds.set(bounds);
@@ -153,7 +153,7 @@ private float calculateRotateDegrees(float fishProgress) {
}
@Override
- public void computeRender(float renderProgress) {
+ protected void computeRender(float renderProgress) {
if (mRiverPath == null) {
return;
}
@@ -169,17 +169,17 @@ public void computeRender(float renderProgress) {
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
}
@Override
- public void reset() {
+ protected void reset() {
}
private Path createFishEyePath(float fishEyeCenterX, float fishEyeCenterY) {
@@ -246,4 +246,17 @@ public float getInterpolation(float input) {
return FISH_MOVE_POINTS[index];
}
}
+
+ public static class Builder {
+ private Context mContext;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public FishLoadingRenderer build() {
+ FishLoadingRenderer loadingRenderer = new FishLoadingRenderer(mContext);
+ return loadingRenderer;
+ }
+ }
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/animal/GhostsEyeLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/animal/GhostsEyeLoadingRenderer.java
index dfd9a52..b13b2a8 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/animal/GhostsEyeLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/animal/GhostsEyeLoadingRenderer.java
@@ -65,7 +65,7 @@ public class GhostsEyeLoadingRenderer extends LoadingRenderer {
private int mColor;
- public GhostsEyeLoadingRenderer(Context context) {
+ private GhostsEyeLoadingRenderer(Context context) {
super(context);
init(context);
setupPaint();
@@ -87,7 +87,7 @@ private void init(Context context) {
mColor = DEFAULT_COLOR;
- setDuration(ANIMATION_DURATION);
+ mDuration = ANIMATION_DURATION;
}
private void setupPaint() {
@@ -99,7 +99,7 @@ private void setupPaint() {
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas, Rect bounds) {
int saveCount = canvas.save();
RectF arcBounds = mTempBounds;
arcBounds.set(bounds);
@@ -120,7 +120,7 @@ public void draw(Canvas canvas, Rect bounds) {
}
@Override
- public void computeRender(float renderProgress) {
+ protected void computeRender(float renderProgress) {
if (renderProgress <= LEFT_EYE_BALL_END_JUMP_OFFSET && renderProgress >= LEFT_EYE_CIRCLE$BALL_START_JUMP_UP_OFFSET) {
float eyeCircle$BallJumpUpProgress = (renderProgress - LEFT_EYE_CIRCLE$BALL_START_JUMP_UP_OFFSET) / (LEFT_EYE_BALL_END_JUMP_OFFSET - LEFT_EYE_CIRCLE$BALL_START_JUMP_UP_OFFSET);
mLeftEyeBallOffsetY = -mMaxEyeJumptDistance * EYE_BALL_INTERPOLATOR.getInterpolation(eyeCircle$BallJumpUpProgress);
@@ -143,17 +143,17 @@ public void computeRender(float renderProgress) {
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
}
@Override
- public void reset() {
+ protected void reset() {
mLeftEyeBallOffsetY = 0.0f;
mRightEyeBallOffsetY = 0.0f;
mLeftEyeCircleOffsetY = 0.0f;
@@ -245,4 +245,17 @@ public float getInterpolation(float input) {
}
}
}
+
+ public static class Builder {
+ private Context mContext;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public GhostsEyeLoadingRenderer build() {
+ GhostsEyeLoadingRenderer loadingRenderer = new GhostsEyeLoadingRenderer(mContext);
+ return loadingRenderer;
+ }
+ }
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/CollisionLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/CollisionLoadingRenderer.java
index fc070d3..fef4662 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/CollisionLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/CollisionLoadingRenderer.java
@@ -6,12 +6,9 @@
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
-import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
-import android.support.annotation.NonNull;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
+import android.support.annotation.Size;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
@@ -23,175 +20,284 @@ public class CollisionLoadingRenderer extends LoadingRenderer {
private static final Interpolator ACCELERATE_INTERPOLATOR = new AccelerateInterpolator();
private static final Interpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator();
- private static final int CIRCLE_COUNT = 7;
+ private static final int MAX_ALPHA = 255;
+ private static final int OVAL_ALPHA = 64;
- //the 2 * 2 is the left and right side offset
- private static final float DEFAULT_WIDTH = 15.0f * (CIRCLE_COUNT + 2 * 2);
- //the 2 * 2 is the top and bottom side offset
- private static final float DEFAULT_HEIGHT = 15.0f * (1 + 2 * 2);
+ private static final int DEFAULT_BALL_COUNT = 7;
+
+ private static final float DEFAULT_OVAL_HEIGHT = 1.5f;
+ private static final float DEFAULT_BALL_RADIUS = 7.5f;
+ private static final float DEFAULT_WIDTH = 15.0f * 11;
+ private static final float DEFAULT_HEIGHT = 15.0f * 4;
- private static final float DURATION_OFFSET = 0.25f;
private static final float START_LEFT_DURATION_OFFSET = 0.25f;
private static final float START_RIGHT_DURATION_OFFSET = 0.5f;
private static final float END_RIGHT_DURATION_OFFSET = 0.75f;
private static final float END_LEFT_DURATION_OFFSET = 1.0f;
- private static final float DEFAULT_STROKE_WIDTH = 2.5f;
-
private static final int[] DEFAULT_COLORS = new int[]{
- Color.RED, Color.GREEN
+ Color.parseColor("#FF28435D"), Color.parseColor("#FFC32720")
};
private static final float[] DEFAULT_POSITIONS = new float[]{
0.0f, 1.0f
};
- private final Paint mPaint = new Paint();
- private final RectF mTempBounds = new RectF();
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ private final RectF mOvalRect = new RectF();
+ @Size(2)
private int[] mColors;
private float[] mPositions;
- private float mEndXOffsetProgress;
- private float mStartXOffsetProgress;
+ private float mOvalVerticalRadius;
+
+ private float mBallRadius;
+ private float mBallCenterY;
+ private float mBallSideOffsets;
+ private float mBallMoveXOffsets;
+ private float mBallQuadCoefficient;
+
+ private float mLeftBallMoveXOffsets;
+ private float mLeftBallMoveYOffsets;
+ private float mRightBallMoveXOffsets;
+ private float mRightBallMoveYOffsets;
+
+ private float mLeftOvalShapeRate;
+ private float mRightOvalShapeRate;
- private float mStrokeWidth;
+ private int mBallCount;
- public CollisionLoadingRenderer(Context context) {
+ private CollisionLoadingRenderer(Context context) {
super(context);
init(context);
+ adjustParams();
setupPaint();
}
private void init(Context context) {
+ mBallRadius = DensityUtil.dip2px(context, DEFAULT_BALL_RADIUS);
mWidth = DensityUtil.dip2px(context, DEFAULT_WIDTH);
mHeight = DensityUtil.dip2px(context, DEFAULT_HEIGHT);
- mStrokeWidth = DensityUtil.dip2px(context, DEFAULT_STROKE_WIDTH);
- }
+ mOvalVerticalRadius = DensityUtil.dip2px(context, DEFAULT_OVAL_HEIGHT);
- private void setupPaint() {
mColors = DEFAULT_COLORS;
mPositions = DEFAULT_POSITIONS;
- mPaint.setStrokeWidth(mStrokeWidth);
- mPaint.setAntiAlias(true);
+ mBallCount = DEFAULT_BALL_COUNT;
+
+ //mBallMoveYOffsets = mBallQuadCoefficient * mBallMoveXOffsets ^ 2
+ // ==> if mBallMoveYOffsets == mBallMoveXOffsets
+ // ==> mBallQuadCoefficient = 1.0f / mBallMoveXOffsets;
+ mBallMoveXOffsets = 1.5f * (2 * mBallRadius);
+ mBallQuadCoefficient = 1.0f / mBallMoveXOffsets;
+ }
+
+ private void adjustParams() {
+ mBallCenterY = mHeight / 2.0f;
+ mBallSideOffsets = (mWidth - mBallRadius * 2.0f * (mBallCount - 2)) / 2;
+ }
+
+ private void setupPaint() {
mPaint.setStyle(Paint.Style.FILL);
+ mPaint.setShader(new LinearGradient(mBallSideOffsets, 0, mWidth - mBallSideOffsets, 0,
+ mColors, mPositions, Shader.TileMode.CLAMP));
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas) {
int saveCount = canvas.save();
- RectF arcBounds = mTempBounds;
- arcBounds.set(bounds);
-
- float cy = mHeight / 2;
- float circleRadius = computeCircleRadius(arcBounds);
-
- float sideOffset = 2.0f * (2 * circleRadius);
- float maxMoveOffset = 1.5f * (2 * circleRadius);
-
- LinearGradient gradient = new LinearGradient(arcBounds.left + sideOffset, 0, arcBounds.right - sideOffset, 0,
- mColors, mPositions, Shader.TileMode.CLAMP);
- mPaint.setShader(gradient);
-
- for (int i = 0; i < CIRCLE_COUNT; i++) {
- if (i == 0 && mStartXOffsetProgress != 0) {
- float xMoveOffset = maxMoveOffset * mStartXOffsetProgress;
- // y = ax^2 --> if x = sideOffset, y = sideOffset ==> a = 1 / sideOffset
- float yMoveOffset = (float) (Math.pow(xMoveOffset, 2) / maxMoveOffset);
- canvas.drawCircle(circleRadius + sideOffset - xMoveOffset, cy - yMoveOffset, circleRadius, mPaint);
- continue;
- }
+ for (int i = 1; i < mBallCount - 1; i++) {
+ mPaint.setAlpha(MAX_ALPHA);
+ canvas.drawCircle(mBallRadius * (i * 2 - 1) + mBallSideOffsets, mBallCenterY, mBallRadius, mPaint);
- if (i == CIRCLE_COUNT - 1 && mEndXOffsetProgress != 0) {
- float xMoveOffset = maxMoveOffset * mEndXOffsetProgress;
- // y = ax^2 --> if x = sideOffset, y = sideOffset / 2 ==> a = 1 / sideOffset
- float yMoveOffset = (float) (Math.pow(xMoveOffset, 2) / maxMoveOffset);
- canvas.drawCircle(circleRadius * (CIRCLE_COUNT * 2 - 1) + sideOffset + xMoveOffset, cy - yMoveOffset, circleRadius, mPaint);
- continue;
- }
-
- canvas.drawCircle(circleRadius * (i * 2 + 1) + sideOffset, cy, circleRadius, mPaint);
+ mOvalRect.set(mBallRadius * (i * 2 - 2) + mBallSideOffsets, mHeight - mOvalVerticalRadius * 2,
+ mBallRadius * (i * 2) + mBallSideOffsets, mHeight);
+ mPaint.setAlpha(OVAL_ALPHA);
+ canvas.drawOval(mOvalRect, mPaint);
}
- canvas.restoreToCount(saveCount);
- }
-
- private float computeCircleRadius(RectF rectBounds) {
- float width = rectBounds.width();
- float height = rectBounds.height();
+ //draw the first ball
+ mPaint.setAlpha(MAX_ALPHA);
+ canvas.drawCircle(mBallSideOffsets - mBallRadius - mLeftBallMoveXOffsets,
+ mBallCenterY - mLeftBallMoveYOffsets, mBallRadius, mPaint);
+
+ mOvalRect.set(mBallSideOffsets - mBallRadius - mBallRadius * mLeftOvalShapeRate - mLeftBallMoveXOffsets,
+ mHeight - mOvalVerticalRadius - mOvalVerticalRadius * mLeftOvalShapeRate,
+ mBallSideOffsets - mBallRadius + mBallRadius * mLeftOvalShapeRate - mLeftBallMoveXOffsets,
+ mHeight - mOvalVerticalRadius + mOvalVerticalRadius * mLeftOvalShapeRate);
+ mPaint.setAlpha(OVAL_ALPHA);
+ canvas.drawOval(mOvalRect, mPaint);
+
+ //draw the last ball
+ mPaint.setAlpha(MAX_ALPHA);
+ canvas.drawCircle(mBallRadius * (mBallCount * 2 - 3) + mBallSideOffsets + mRightBallMoveXOffsets,
+ mBallCenterY - mRightBallMoveYOffsets, mBallRadius, mPaint);
+
+ mOvalRect.set(mBallRadius * (mBallCount * 2 - 3) - mBallRadius * mRightOvalShapeRate + mBallSideOffsets + mRightBallMoveXOffsets,
+ mHeight - mOvalVerticalRadius - mOvalVerticalRadius * mRightOvalShapeRate,
+ mBallRadius * (mBallCount * 2 - 3) + mBallRadius * mRightOvalShapeRate + mBallSideOffsets + mRightBallMoveXOffsets,
+ mHeight - mOvalVerticalRadius + mOvalVerticalRadius * mRightOvalShapeRate);
+ mPaint.setAlpha(OVAL_ALPHA);
+ canvas.drawOval(mOvalRect, mPaint);
- //CIRCLE_COUNT + 4 is the sliding distance of both sides
- float radius = Math.min(width / (CIRCLE_COUNT + 4) / 2, height / 2);
- return radius;
+ canvas.restoreToCount(saveCount);
}
@Override
- public void computeRender(float renderProgress) {
-
- // Moving the start offset to left only occurs in the first 25% of a
- // single ring animation
+ protected void computeRender(float renderProgress) {
+ // Moving the left ball to the left sides only occurs in the first 25% of a jump animation
if (renderProgress <= START_LEFT_DURATION_OFFSET) {
- float startLeftOffsetProgress = renderProgress / DURATION_OFFSET;
- mStartXOffsetProgress = DECELERATE_INTERPOLATOR.getInterpolation(startLeftOffsetProgress);
-
- invalidateSelf();
+ float startLeftOffsetProgress = renderProgress / START_LEFT_DURATION_OFFSET;
+ computeLeftBallMoveOffsets(DECELERATE_INTERPOLATOR.getInterpolation(startLeftOffsetProgress));
return;
}
- // Moving the start offset to left only occurs between 25% and 50% of a
- // single ring animation
+ // Moving the left ball to the origin location only occurs between 25% and 50% of a jump ring animation
if (renderProgress <= START_RIGHT_DURATION_OFFSET) {
- float startRightOffsetProgress = (renderProgress - START_LEFT_DURATION_OFFSET) / DURATION_OFFSET;
- mStartXOffsetProgress = ACCELERATE_INTERPOLATOR.getInterpolation(1.0f - startRightOffsetProgress);
-
- invalidateSelf();
+ float startRightOffsetProgress = (renderProgress - START_LEFT_DURATION_OFFSET) / (START_RIGHT_DURATION_OFFSET - START_LEFT_DURATION_OFFSET);
+ computeLeftBallMoveOffsets(ACCELERATE_INTERPOLATOR.getInterpolation(1.0f - startRightOffsetProgress));
return;
}
- // Moving the end offset to right starts between 50% and 75% a single ring
- // animation completes
+ // Moving the right ball to the right sides only occurs between 50% and 75% of a jump animation
if (renderProgress <= END_RIGHT_DURATION_OFFSET) {
- float endRightOffsetProgress = (renderProgress - START_RIGHT_DURATION_OFFSET) / DURATION_OFFSET;
- mEndXOffsetProgress = DECELERATE_INTERPOLATOR.getInterpolation(endRightOffsetProgress);
-
- invalidateSelf();
+ float endRightOffsetProgress = (renderProgress - START_RIGHT_DURATION_OFFSET) / (END_RIGHT_DURATION_OFFSET - START_RIGHT_DURATION_OFFSET);
+ computeRightBallMoveOffsets(DECELERATE_INTERPOLATOR.getInterpolation(endRightOffsetProgress));
return;
}
- // Moving the end offset to left starts after 75% of a single ring
- // animation completes
+ // Moving the right ball to the origin location only occurs after 75% of a jump animation
if (renderProgress <= END_LEFT_DURATION_OFFSET) {
- float endRightOffsetProgress = (renderProgress - END_RIGHT_DURATION_OFFSET) / DURATION_OFFSET;
- mEndXOffsetProgress = ACCELERATE_INTERPOLATOR.getInterpolation(1 - endRightOffsetProgress);
-
- invalidateSelf();
+ float endRightOffsetProgress = (renderProgress - END_RIGHT_DURATION_OFFSET) / (END_LEFT_DURATION_OFFSET - END_RIGHT_DURATION_OFFSET);
+ computeRightBallMoveOffsets(ACCELERATE_INTERPOLATOR.getInterpolation(1 - endRightOffsetProgress));
return;
}
+
+ }
+
+ private void computeLeftBallMoveOffsets(float progress) {
+ mRightBallMoveXOffsets = 0.0f;
+ mRightBallMoveYOffsets = 0.0f;
+
+ mLeftOvalShapeRate = 1.0f - progress;
+ mLeftBallMoveXOffsets = mBallMoveXOffsets * progress;
+ mLeftBallMoveYOffsets = (float) (Math.pow(mLeftBallMoveXOffsets, 2) * mBallQuadCoefficient);
+ }
+
+ private void computeRightBallMoveOffsets(float progress) {
+ mLeftBallMoveXOffsets = 0.0f;
+ mLeftBallMoveYOffsets = 0.0f;
+
+ mRightOvalShapeRate = 1.0f - progress;
+ mRightBallMoveXOffsets = mBallMoveXOffsets * progress;
+ mRightBallMoveYOffsets = (float) (Math.pow(mRightBallMoveXOffsets, 2) * mBallQuadCoefficient);
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
}
@Override
- public void reset() {
+ protected void reset() {
}
- public void setColors(@NonNull int[] colors) {
- mColors = colors;
+ private void apply(Builder builder) {
+ this.mWidth = builder.mWidth > 0 ? builder.mWidth : this.mWidth;
+ this.mHeight = builder.mHeight > 0 ? builder.mHeight : this.mHeight;
+
+ this.mOvalVerticalRadius = builder.mOvalVerticalRadius > 0 ? builder.mOvalVerticalRadius : this.mOvalVerticalRadius;
+ this.mBallRadius = builder.mBallRadius > 0 ? builder.mBallRadius : this.mBallRadius;
+ this.mBallMoveXOffsets = builder.mBallMoveXOffsets > 0 ? builder.mBallMoveXOffsets : this.mBallMoveXOffsets;
+ this.mBallQuadCoefficient = builder.mBallQuadCoefficient > 0 ? builder.mBallQuadCoefficient : this.mBallQuadCoefficient;
+ this.mBallCount = builder.mBallCount > 0 ? builder.mBallCount : this.mBallCount;
+
+ this.mDuration = builder.mDuration > 0 ? builder.mDuration : this.mDuration;
+
+ this.mColors = builder.mColors != null ? builder.mColors : this.mColors;
+
+ adjustParams();
+ setupPaint();
}
- public void setPositions(@NonNull float[] positions) {
- mPositions = positions;
+ public static class Builder {
+ private Context mContext;
+
+ private int mWidth;
+ private int mHeight;
+
+ private float mOvalVerticalRadius;
+
+ private int mBallCount;
+ private float mBallRadius;
+ private float mBallMoveXOffsets;
+ private float mBallQuadCoefficient;
+
+ private int mDuration;
+
+ @Size(2)
+ private int[] mColors;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public Builder setWidth(int width) {
+ this.mWidth = width;
+ return this;
+ }
+
+ public Builder setHeight(int height) {
+ this.mHeight = height;
+ return this;
+ }
+
+ public Builder setOvalVerticalRadius(int ovalVerticalRadius) {
+ this.mOvalVerticalRadius = ovalVerticalRadius;
+ return this;
+ }
+
+ public Builder setBallRadius(int ballRadius) {
+ this.mBallRadius = ballRadius;
+ return this;
+ }
+
+ public Builder setBallMoveXOffsets(int ballMoveXOffsets) {
+ this.mBallMoveXOffsets = ballMoveXOffsets;
+ return this;
+ }
+
+ public Builder setBallQuadCoefficient(int ballQuadCoefficient) {
+ this.mBallQuadCoefficient = ballQuadCoefficient;
+ return this;
+ }
+
+ public Builder setBallCount(int ballCount) {
+ this.mBallCount = ballCount;
+ return this;
+ }
+
+ public Builder setColors(@Size(2) int[] colors) {
+ this.mColors = colors;
+ return this;
+ }
+
+ public Builder setDuration(int duration) {
+ this.mDuration = duration;
+ return this;
+ }
+
+ public CollisionLoadingRenderer build() {
+ CollisionLoadingRenderer loadingRenderer = new CollisionLoadingRenderer(mContext);
+ loadingRenderer.apply(this);
+ return loadingRenderer;
+ }
}
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/DanceLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/DanceLoadingRenderer.java
index cef6131..9d72c9a 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/DanceLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/DanceLoadingRenderer.java
@@ -83,7 +83,7 @@ public class DanceLoadingRenderer extends LoadingRenderer {
private int mColor;
private int mArcColor;
- public DanceLoadingRenderer(Context context) {
+ private DanceLoadingRenderer(Context context) {
super(context);
init(context);
setupPaint();
@@ -95,8 +95,8 @@ private void init(Context context) {
mDanceBallRadius = DensityUtil.dip2px(context, DEFAULT_DANCE_BALL_RADIUS);
setColor(DEFAULT_COLOR);
- setInsets((int) getWidth(), (int) getHeight());
- setDuration(ANIMATION_DURATION);
+ setInsets((int) mWidth, (int) mHeight);
+ mDuration = ANIMATION_DURATION;
}
private void setupPaint() {
@@ -106,7 +106,7 @@ private void setupPaint() {
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas, Rect bounds) {
int saveCount = canvas.save();
mTempBounds.set(bounds);
@@ -149,7 +149,7 @@ public void draw(Canvas canvas, Rect bounds) {
}
@Override
- public void computeRender(float renderProgress) {
+ protected void computeRender(float renderProgress) {
float radius = Math.min(mCurrentBounds.height(), mCurrentBounds.width()) / 2.0f;
//the origin coordinate is the centerLeft of the field mCurrentBounds
float originCoordinateX = mCurrentBounds.left;
@@ -259,47 +259,47 @@ public void computeRender(float renderProgress) {
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
+
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
+
}
@Override
- public void reset() {
+ protected void reset() {
mScale = 1.0f;
mRotation = 0;
}
- public void setColor(int color) {
+ private void setColor(int color) {
mColor = color;
mArcColor = halfAlphaColor(mColor);
}
- public void setRotation(float rotation) {
+ private void setRotation(float rotation) {
mRotation = rotation;
- invalidateSelf();
+
}
- public void setDanceBallRadius(float danceBallRadius) {
+ private void setDanceBallRadius(float danceBallRadius) {
this.mDanceBallRadius = danceBallRadius;
- invalidateSelf();
+
}
- public float getDanceBallRadius() {
+ private float getDanceBallRadius() {
return mDanceBallRadius;
}
- public float getRotation() {
+ private float getRotation() {
return mRotation;
}
- public void setInsets(int width, int height) {
+ private void setInsets(int width, int height) {
final float minEdge = (float) Math.min(width, height);
float insets;
if (mCenterRadius <= 0 || minEdge < 0) {
@@ -321,4 +321,17 @@ private int halfAlphaColor(int colorValue) {
| (startG << 8)
| startB;
}
+
+ public static class Builder {
+ private Context mContext;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public DanceLoadingRenderer build() {
+ DanceLoadingRenderer loadingRenderer = new DanceLoadingRenderer(mContext);
+ return loadingRenderer;
+ }
+ }
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/GuardLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/GuardLoadingRenderer.java
index 3ce439a..7a1c971 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/GuardLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/GuardLoadingRenderer.java
@@ -65,10 +65,10 @@ public class GuardLoadingRenderer extends LoadingRenderer {
private PathMeasure mPathMeasure;
- public GuardLoadingRenderer(Context context) {
+ private GuardLoadingRenderer(Context context) {
super(context);
- setDuration(ANIMATION_DURATION);
+ mDuration = ANIMATION_DURATION;
init(context);
setupPaint();
}
@@ -88,11 +88,11 @@ private void setupPaint() {
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeCap(Paint.Cap.ROUND);
- setInsets((int) getWidth(), (int) getHeight());
+ setInsets((int) mWidth, (int) mHeight);
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas, Rect bounds) {
RectF arcBounds = mTempBounds;
arcBounds.set(bounds);
arcBounds.inset(mStrokeInset, mStrokeInset);
@@ -129,7 +129,7 @@ public void draw(Canvas canvas, Rect bounds) {
}
@Override
- public void computeRender(float renderProgress) {
+ protected void computeRender(float renderProgress) {
if (renderProgress <= START_TRIM_DURATION_OFFSET) {
final float startTrimProgress = (renderProgress) / START_TRIM_DURATION_OFFSET;
mEndTrim = -MATERIAL_INTERPOLATOR.getInterpolation(startTrimProgress);
@@ -180,19 +180,19 @@ public void computeRender(float renderProgress) {
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
+
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
+
}
@Override
- public void reset() {
+ protected void reset() {
mScale = 1.0f;
mEndTrim = 0.0f;
mRotation = 0.0f;
@@ -200,10 +200,6 @@ public void reset() {
mWaveProgress = 1.0f;
}
- public void setColor(int color) {
- mColor = color;
- }
-
private Path createSkipBallPath() {
float radius = Math.min(mCurrentBounds.width(), mCurrentBounds.height()) / 2.0f;
float radiusPow2 = (float) Math.pow(radius, 2.0f);
@@ -237,46 +233,7 @@ private Path createSkipBallPath() {
return path;
}
- public void setStartTrim(float startTrim) {
- mStartTrim = startTrim;
- invalidateSelf();
- }
-
- public float getStartTrim() {
- return mStartTrim;
- }
-
- public void setEndTrim(float endTrim) {
- mEndTrim = endTrim;
- invalidateSelf();
- }
-
- public float getEndTrim() {
- return mEndTrim;
- }
-
- public void setRotation(float rotation) {
- mRotation = rotation;
- invalidateSelf();
- }
-
- public void setScale(float scale) {
- this.mScale = scale;
- }
-
- public float getScale() {
- return mScale;
- }
-
- public void setSkipBallSize(float skipBallSize) {
- this.mSkipBallSize = skipBallSize;
- }
-
- public float getSkipBallSize() {
- return mSkipBallSize;
- }
-
- public void setInsets(int width, int height) {
+ private void setInsets(int width, int height) {
final float minEdge = (float) Math.min(width, height);
float insets;
if (mCenterRadius <= 0 || minEdge < 0) {
@@ -286,4 +243,17 @@ public void setInsets(int width, int height) {
}
mStrokeInset = insets;
}
+
+ public static class Builder {
+ private Context mContext;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public GuardLoadingRenderer build() {
+ GuardLoadingRenderer loadingRenderer = new GuardLoadingRenderer(mContext);
+ return loadingRenderer;
+ }
+ }
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/SwapLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/SwapLoadingRenderer.java
index 423df50..c759723 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/SwapLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/jump/SwapLoadingRenderer.java
@@ -5,155 +5,223 @@
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.support.v4.view.animation.FastOutSlowInInterpolator;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
+import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;
import app.dinus.com.loadingdrawable.DensityUtil;
import app.dinus.com.loadingdrawable.render.LoadingRenderer;
public class SwapLoadingRenderer extends LoadingRenderer {
- private static final Interpolator MATERIAL_INTERPOLATOR = new FastOutSlowInInterpolator();
+ private static final Interpolator ACCELERATE_DECELERATE_INTERPOLATOR = new AccelerateDecelerateInterpolator();
private static final long ANIMATION_DURATION = 2500;
- private static final int CIRCLE_COUNT = 5;
+ private static final int DEFAULT_CIRCLE_COUNT = 5;
- //(CIRCLE_COUNT - 1) / 2 is the Circle interval width; the 2 * 2 is the both side inset
- private static final float DEFAULT_WIDTH = 15.0f * (CIRCLE_COUNT + (CIRCLE_COUNT - 1) / 2 + 2 * 2);
- //the 2 * 2 is the both side inset
- private static final float DEFAULT_HEIGHT = 15.0f * (1 + 2 * 2);
+ private static final float DEFAULT_BALL_RADIUS = 7.5f;
+ private static final float DEFAULT_WIDTH = 15.0f * 11;
+ private static final float DEFAULT_HEIGHT = 15.0f * 5;
private static final float DEFAULT_STROKE_WIDTH = 1.5f;
private static final int DEFAULT_COLOR = Color.WHITE;
- private final Paint mPaint = new Paint();
- private final RectF mTempBounds = new RectF();
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int mColor;
private int mSwapIndex;
+ private int mBallCount;
- private float mSwapThreshold;
- private float mSwapXOffsetProgress;
+ private float mBallSideOffsets;
+ private float mBallCenterY;
+ private float mBallRadius;
+ private float mBallInterval;
+ private float mSwapBallOffsetX;
+ private float mSwapBallOffsetY;
+ private float mASwapThreshold;
private float mStrokeWidth;
- public SwapLoadingRenderer(Context context) {
+ private SwapLoadingRenderer(Context context) {
super(context);
- setDuration(ANIMATION_DURATION);
init(context);
+ adjustParams();
setupPaint();
}
private void init(Context context) {
mWidth = DensityUtil.dip2px(context, DEFAULT_WIDTH);
mHeight = DensityUtil.dip2px(context, DEFAULT_HEIGHT);
+ mBallRadius = DensityUtil.dip2px(context, DEFAULT_BALL_RADIUS);
mStrokeWidth = DensityUtil.dip2px(context, DEFAULT_STROKE_WIDTH);
- mSwapThreshold = 1.0f / CIRCLE_COUNT;
+ mColor = DEFAULT_COLOR;
+ mDuration = ANIMATION_DURATION;
+ mBallCount = DEFAULT_CIRCLE_COUNT;
+
+ mBallInterval = mBallRadius;
}
- private void setupPaint() {
- mColor = DEFAULT_COLOR;
+ private void adjustParams() {
+ mBallCenterY = mHeight / 2.0f;
+ mBallSideOffsets = (mWidth - mBallRadius * 2 * mBallCount - mBallInterval * (mBallCount - 1)) / 2.0f;
- mPaint.setAntiAlias(true);
- mPaint.setStrokeWidth(mStrokeWidth);
- mPaint.setStyle(Paint.Style.FILL);
+ mASwapThreshold = 1.0f / mBallCount;
}
- @Override
- public void draw(Canvas canvas, Rect bounds) {
+ private void setupPaint() {
mPaint.setColor(mColor);
+ mPaint.setStrokeWidth(mStrokeWidth);
+ }
+ @Override
+ protected void draw(Canvas canvas) {
int saveCount = canvas.save();
- RectF arcBounds = mTempBounds;
- arcBounds.set(bounds);
-
- float cy = mHeight / 2;
- float circleRadius = computeCircleRadius(arcBounds);
-
- float sideOffset = 2.0f * (2 * circleRadius);
- float intervalWidth = circleRadius;
-
- float circleDiameter = mSwapIndex == CIRCLE_COUNT - 1
- ? circleRadius * (CIRCLE_COUNT - 1) * 3
- : circleRadius * 3;
-
- //x^2 + y^2 = (3 * circleRadius / 2) ^ 2
- float xMoveOffset = mSwapIndex == CIRCLE_COUNT - 1
- ? -mSwapXOffsetProgress * circleDiameter
- : mSwapXOffsetProgress * circleDiameter;
- //the y axial symmetry
- float xCoordinate = mSwapIndex == CIRCLE_COUNT - 1
- ? xMoveOffset + circleDiameter / 2
- : xMoveOffset - circleDiameter / 2;
- float yMoveOffset = (float) (mSwapIndex % 2 == 0 && mSwapIndex != CIRCLE_COUNT - 1
- ? Math.sqrt(Math.pow(circleDiameter / 2, 2.0f) - Math.pow(xCoordinate, 2.0f))
- : -Math.sqrt(Math.pow(circleDiameter / 2, 2.0f) - Math.pow(xCoordinate, 2.0f)));
-
- for (int i = 0; i < CIRCLE_COUNT; i++) {
+ for (int i = 0; i < mBallCount; i++) {
if (i == mSwapIndex) {
mPaint.setStyle(Paint.Style.FILL);
- canvas.drawCircle(circleRadius * (i * 2 + 1) + sideOffset + i * intervalWidth + xMoveOffset
- , cy - yMoveOffset, circleRadius - mStrokeWidth / 2, mPaint);
- } else if (i == (mSwapIndex + 1) % CIRCLE_COUNT) {
+ canvas.drawCircle(mBallSideOffsets + mBallRadius * (i * 2 + 1) + i * mBallInterval + mSwapBallOffsetX
+ , mBallCenterY - mSwapBallOffsetY, mBallRadius, mPaint);
+ } else if (i == (mSwapIndex + 1) % mBallCount) {
mPaint.setStyle(Paint.Style.STROKE);
-
- canvas.drawCircle(circleRadius * (i * 2 + 1) + sideOffset + i * intervalWidth - xMoveOffset
- , cy + yMoveOffset, circleRadius - mStrokeWidth / 2, mPaint);
+ canvas.drawCircle(mBallSideOffsets + mBallRadius * (i * 2 + 1) + i * mBallInterval - mSwapBallOffsetX
+ , mBallCenterY + mSwapBallOffsetY, mBallRadius - mStrokeWidth / 2, mPaint);
} else {
mPaint.setStyle(Paint.Style.STROKE);
-
- canvas.drawCircle(circleRadius * (i * 2 + 1) + sideOffset + i * intervalWidth, cy,
- circleRadius - mStrokeWidth / 2, mPaint);
+ canvas.drawCircle(mBallSideOffsets + mBallRadius * (i * 2 + 1) + i * mBallInterval, mBallCenterY
+ , mBallRadius - mStrokeWidth / 2, mPaint);
}
-
}
canvas.restoreToCount(saveCount);
}
- private float computeCircleRadius(RectF rectBounds) {
- float width = rectBounds.width();
- float height = rectBounds.height();
+ @Override
+ protected void computeRender(float renderProgress) {
+ mSwapIndex = (int) (renderProgress / mASwapThreshold);
- //CIRCLE_COUNT + 4 is the sliding distance of both sides
- float radius = Math.min(width / (CIRCLE_COUNT + (CIRCLE_COUNT - 1) / 2 + 2 * 2) / 2, height / 2);
- return radius;
- }
+ // Swap trace : x^2 + y^2 = r ^ 2
+ float swapTraceProgress = ACCELERATE_DECELERATE_INTERPOLATOR.getInterpolation(
+ (renderProgress - mSwapIndex * mASwapThreshold) / mASwapThreshold);
- @Override
- public void computeRender(float renderProgress) {
- mSwapIndex = (int) (renderProgress / mSwapThreshold);
- mSwapXOffsetProgress = MATERIAL_INTERPOLATOR.getInterpolation(
- (renderProgress - mSwapIndex * mSwapThreshold) / mSwapThreshold);
+ float swapTraceRadius = mSwapIndex == mBallCount - 1
+ ? (mBallRadius * 2 * (mBallCount - 1) + mBallInterval * (mBallCount - 1)) / 2
+ : (mBallRadius * 2 + mBallInterval) / 2;
+
+ // Calculate the X offset of the swap ball
+ mSwapBallOffsetX = mSwapIndex == mBallCount - 1
+ ? -swapTraceProgress * swapTraceRadius * 2
+ : swapTraceProgress * swapTraceRadius * 2;
+
+ // if mSwapIndex == mBallCount - 1 then (swapTraceRadius, swapTraceRadius) as the origin of coordinates
+ // else (-swapTraceRadius, -swapTraceRadius) as the origin of coordinates
+ float xCoordinate = mSwapIndex == mBallCount - 1
+ ? mSwapBallOffsetX + swapTraceRadius
+ : mSwapBallOffsetX - swapTraceRadius;
+
+ // Calculate the Y offset of the swap ball
+ mSwapBallOffsetY = (float) (mSwapIndex % 2 == 0 && mSwapIndex != mBallCount - 1
+ ? Math.sqrt(Math.pow(swapTraceRadius, 2.0f) - Math.pow(xCoordinate, 2.0f))
+ : -Math.sqrt(Math.pow(swapTraceRadius, 2.0f) - Math.pow(xCoordinate, 2.0f)));
- invalidateSelf();
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
}
@Override
- public void reset() {
+ protected void reset() {
}
- public void setColor(int color) {
- mColor = color;
+ private void apply(Builder builder) {
+ this.mWidth = builder.mWidth > 0 ? builder.mWidth : this.mWidth;
+ this.mHeight = builder.mHeight > 0 ? builder.mHeight : this.mHeight;
+ this.mStrokeWidth = builder.mStrokeWidth > 0 ? builder.mStrokeWidth : this.mStrokeWidth;
+
+ this.mBallRadius = builder.mBallRadius > 0 ? builder.mBallRadius : this.mBallRadius;
+ this.mBallInterval = builder.mBallInterval > 0 ? builder.mBallInterval : this.mBallInterval;
+ this.mBallCount = builder.mBallCount > 0 ? builder.mBallCount : this.mBallCount;
+
+ this.mColor = builder.mColor != 0 ? builder.mColor : this.mColor;
+
+ this.mDuration = builder.mDuration > 0 ? builder.mDuration : this.mDuration;
+
+ adjustParams();
+ setupPaint();
+ }
+
+ public static class Builder {
+ private Context mContext;
+
+ private int mWidth;
+ private int mHeight;
+ private int mStrokeWidth;
+
+ private int mBallCount;
+ private int mBallRadius;
+ private int mBallInterval;
+
+ private int mDuration;
+
+ private int mColor;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public Builder setWidth(int width) {
+ this.mWidth = width;
+ return this;
+ }
+
+ public Builder setHeight(int height) {
+ this.mHeight = height;
+ return this;
+ }
+
+ public Builder setStrokeWidth(int strokeWidth) {
+ this.mStrokeWidth = strokeWidth;
+ return this;
+ }
+
+ public Builder setBallRadius(int ballRadius) {
+ this.mBallRadius = ballRadius;
+ return this;
+ }
+
+ public Builder setBallInterval(int ballInterval) {
+ this.mBallInterval = ballInterval;
+ return this;
+ }
+
+ public Builder setBallCount(int ballCount) {
+ this.mBallCount = ballCount;
+ return this;
+ }
+
+ public Builder setColor(int color) {
+ this.mColor = color;
+ return this;
+ }
+
+ public Builder setDuration(int duration) {
+ this.mDuration = duration;
+ return this;
+ }
+
+ public SwapLoadingRenderer build() {
+ SwapLoadingRenderer loadingRenderer = new SwapLoadingRenderer(mContext);
+ loadingRenderer.apply(this);
+ return loadingRenderer;
+ }
}
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/GearLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/GearLoadingRenderer.java
index ac5182d..b1f4c00 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/GearLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/GearLoadingRenderer.java
@@ -7,19 +7,16 @@
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
-import android.graphics.Rect;
import android.graphics.RectF;
-import android.util.DisplayMetrics;
+import android.support.annotation.IntRange;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
import app.dinus.com.loadingdrawable.DensityUtil;
import app.dinus.com.loadingdrawable.render.LoadingRenderer;
public class GearLoadingRenderer extends LoadingRenderer {
- private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
private static final Interpolator ACCELERATE_INTERPOLATOR = new AccelerateInterpolator();
private static final Interpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator();
@@ -28,10 +25,9 @@ public class GearLoadingRenderer extends LoadingRenderer {
private static final int MAX_ALPHA = 255;
private static final int DEGREE_360 = 360;
- private static final float MIN_SWIPE_DEGREE = 0.1f;
- private static final float MAX_SWIPE_DEGREES = 0.17f * DEGREE_360;
+ private static final int DEFAULT_GEAR_SWIPE_DEGREES = 60;
+
private static final float FULL_GROUP_ROTATION = 3.0f * DEGREE_360;
- private static final float MAX_ROTATION_INCREMENT = 0.25f * DEGREE_360;
private static final float START_SCALE_DURATION_OFFSET = 0.3f;
private static final float START_TRIM_DURATION_OFFSET = 0.5f;
@@ -63,7 +59,10 @@ public void onAnimationStart(Animator animation) {
}
};
- private int mCurrentColor;
+ private int mColor;
+
+ private int mGearCount;
+ private int mGearSwipeDegrees;
private float mStrokeInset;
@@ -74,15 +73,13 @@ public void onAnimationStart(Animator animation) {
private float mEndDegrees;
private float mStartDegrees;
private float mSwipeDegrees;
- private float mRotationIncrement;
private float mOriginEndDegrees;
private float mOriginStartDegrees;
- private float mOriginRotationIncrement;
private float mStrokeWidth;
private float mCenterRadius;
- public GearLoadingRenderer(Context context) {
+ private GearLoadingRenderer(Context context) {
super(context);
init(context);
@@ -94,7 +91,10 @@ private void init(Context context) {
mStrokeWidth = DensityUtil.dip2px(context, DEFAULT_STROKE_WIDTH);
mCenterRadius = DensityUtil.dip2px(context, DEFAULT_CENTER_RADIUS);
- mCurrentColor = DEFAULT_COLOR;
+ mColor = DEFAULT_COLOR;
+
+ mGearCount = GEAR_COUNT;
+ mGearSwipeDegrees = DEFAULT_GEAR_SWIPE_DEGREES;
}
private void setupPaint() {
@@ -103,118 +103,185 @@ private void setupPaint() {
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeCap(Paint.Cap.ROUND);
- setInsets((int) getWidth(), (int) getHeight());
+ initStrokeInset(mWidth, mHeight);
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas) {
int saveCount = canvas.save();
- canvas.rotate(mGroupRotation, bounds.exactCenterX(), bounds.exactCenterY());
- RectF arcBounds = mTempBounds;
- arcBounds.set(bounds);
- arcBounds.inset(mStrokeInset, mStrokeInset);
+ mTempBounds.set(mBounds);
+ mTempBounds.inset(mStrokeInset, mStrokeInset);
+ mTempBounds.inset(mTempBounds.width() * (1.0f - mScale) / 2.0f, mTempBounds.width() * (1.0f - mScale) / 2.0f);
- arcBounds.inset(arcBounds.width() * (1.0f - mScale) / 2.0f, arcBounds.width() * (1.0f - mScale) / 2.0f);
+ canvas.rotate(mGroupRotation, mTempBounds.centerX(), mTempBounds.centerY());
- mPaint.setColor(mCurrentColor);
+ mPaint.setColor(mColor);
mPaint.setAlpha((int) (MAX_ALPHA * mScale));
mPaint.setStrokeWidth(mStrokeWidth * mScale);
- for (int i = 0; i < GEAR_COUNT; i++) {
- canvas.drawArc(arcBounds, mStartDegrees + DEGREE_360 / GEAR_COUNT * i, mSwipeDegrees, false, mPaint);
+
+ if (mSwipeDegrees != 0) {
+ for (int i = 0; i < mGearCount; i++) {
+ canvas.drawArc(mTempBounds, mStartDegrees + DEGREE_360 / mGearCount * i, mSwipeDegrees, false, mPaint);
+ }
}
canvas.restoreToCount(saveCount);
}
@Override
- public void computeRender(float renderProgress) {
- // Scaling up the start size only occurs in the first 20% of a
- // single ring animation
+ protected void computeRender(float renderProgress) {
+ // Scaling up the start size only occurs in the first 20% of a single ring animation
if (renderProgress <= START_SCALE_DURATION_OFFSET) {
float startScaleProgress = (renderProgress) / START_SCALE_DURATION_OFFSET;
mScale = DECELERATE_INTERPOLATOR.getInterpolation(startScaleProgress);
}
- // Moving the start trim only occurs between 20% to 50% of a
- // single ring animation
+ // Moving the start trim only occurs between 20% to 50% of a single ring animation
if (renderProgress <= START_TRIM_DURATION_OFFSET && renderProgress > START_SCALE_DURATION_OFFSET) {
float startTrimProgress = (renderProgress - START_SCALE_DURATION_OFFSET) / (START_TRIM_DURATION_OFFSET - START_SCALE_DURATION_OFFSET);
- mStartDegrees = mOriginStartDegrees + MAX_SWIPE_DEGREES * LINEAR_INTERPOLATOR.getInterpolation(startTrimProgress);
+ mStartDegrees = mOriginStartDegrees + mGearSwipeDegrees * startTrimProgress;
}
- // Moving the end trim starts between 50% to 80% of a single ring
- // animation completes
+ // Moving the end trim starts between 50% to 80% of a single ring animation
if (renderProgress <= END_TRIM_DURATION_OFFSET && renderProgress > START_TRIM_DURATION_OFFSET) {
float endTrimProgress = (renderProgress - START_TRIM_DURATION_OFFSET) / (END_TRIM_DURATION_OFFSET - START_TRIM_DURATION_OFFSET);
- mEndDegrees = mOriginEndDegrees + MAX_SWIPE_DEGREES * LINEAR_INTERPOLATOR.getInterpolation(endTrimProgress);
+ mEndDegrees = mOriginEndDegrees + mGearSwipeDegrees * endTrimProgress;
}
- // Scaling down the end size starts after 80% of a single ring
- // animation completes
+ // Scaling down the end size starts after 80% of a single ring animation
if (renderProgress > END_TRIM_DURATION_OFFSET) {
float endScaleProgress = (renderProgress - END_TRIM_DURATION_OFFSET) / (END_SCALE_DURATION_OFFSET - END_TRIM_DURATION_OFFSET);
mScale = 1.0f - ACCELERATE_INTERPOLATOR.getInterpolation(endScaleProgress);
}
- if (Math.abs(mEndDegrees - mStartDegrees) > MIN_SWIPE_DEGREE) {
- mSwipeDegrees = mEndDegrees - mStartDegrees;
- }
-
if (renderProgress <= END_TRIM_DURATION_OFFSET && renderProgress > START_SCALE_DURATION_OFFSET) {
float rotateProgress = (renderProgress - START_SCALE_DURATION_OFFSET) / (END_TRIM_DURATION_OFFSET - START_SCALE_DURATION_OFFSET);
mGroupRotation = ((FULL_GROUP_ROTATION / NUM_POINTS) * rotateProgress) + (FULL_GROUP_ROTATION * (mRotationCount / NUM_POINTS));
- mRotationIncrement = mOriginRotationIncrement + (MAX_ROTATION_INCREMENT * rotateProgress);
+ }
+
+ if (Math.abs(mEndDegrees - mStartDegrees) > 0) {
+ mSwipeDegrees = mEndDegrees - mStartDegrees;
}
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
}
@Override
- public void reset() {
+ protected void reset() {
resetOriginals();
}
- public void setColor(int color) {
- mCurrentColor = color;
- }
-
- private void setInsets(int width, int height) {
- final float minEdge = (float) Math.min(width, height);
- float insets;
- if (mCenterRadius <= 0 || minEdge < 0) {
- insets = (float) Math.ceil(mStrokeWidth / 2.0f);
- } else {
- insets = minEdge / 2.0f - mCenterRadius;
- }
- mStrokeInset = insets;
+ private void initStrokeInset(float width, float height) {
+ float minSize = Math.min(width, height);
+ float strokeInset = minSize / 2.0f - mCenterRadius;
+ float minStrokeInset = (float) Math.ceil(mStrokeWidth / 2.0f);
+ mStrokeInset = strokeInset < minStrokeInset ? minStrokeInset : strokeInset;
}
private void storeOriginals() {
mOriginEndDegrees = mEndDegrees;
- mOriginStartDegrees = mStartDegrees;
- mOriginRotationIncrement = mRotationIncrement;
+ mOriginStartDegrees = mEndDegrees;
}
private void resetOriginals() {
mOriginEndDegrees = 0;
mOriginStartDegrees = 0;
- mOriginRotationIncrement = 0;
mEndDegrees = 0;
mStartDegrees = 0;
- mRotationIncrement = 0;
- mSwipeDegrees = MIN_SWIPE_DEGREE;
+ mSwipeDegrees = 1;
+ }
+
+ private void apply(Builder builder) {
+ this.mWidth = builder.mWidth > 0 ? builder.mWidth : this.mWidth;
+ this.mHeight = builder.mHeight > 0 ? builder.mHeight : this.mHeight;
+ this.mStrokeWidth = builder.mStrokeWidth > 0 ? builder.mStrokeWidth : this.mStrokeWidth;
+ this.mCenterRadius = builder.mCenterRadius > 0 ? builder.mCenterRadius : this.mCenterRadius;
+
+ this.mDuration = builder.mDuration > 0 ? builder.mDuration : this.mDuration;
+
+ this.mColor = builder.mColor != 0 ? builder.mColor : this.mColor;
+
+ this.mGearCount = builder.mGearCount > 0 ? builder.mGearCount : this.mGearCount;
+ this.mGearSwipeDegrees = builder.mGearSwipeDegrees > 0 ? builder.mGearSwipeDegrees : this.mGearSwipeDegrees;
+
+ setupPaint();
+ initStrokeInset(this.mWidth, this.mHeight);
+ }
+
+ public static class Builder {
+ private Context mContext;
+
+ private int mWidth;
+ private int mHeight;
+ private int mStrokeWidth;
+ private int mCenterRadius;
+
+ private int mDuration;
+
+ private int mColor;
+
+ private int mGearCount;
+ private int mGearSwipeDegrees;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public Builder setWidth(int width) {
+ this.mWidth = width;
+ return this;
+ }
+
+ public Builder setHeight(int height) {
+ this.mHeight = height;
+ return this;
+ }
+
+ public Builder setStrokeWidth(int strokeWidth) {
+ this.mStrokeWidth = strokeWidth;
+ return this;
+ }
+
+ public Builder setCenterRadius(int centerRadius) {
+ this.mCenterRadius = centerRadius;
+ return this;
+ }
+
+ public Builder setDuration(int duration) {
+ this.mDuration = duration;
+ return this;
+ }
+
+ public Builder setColor(int color) {
+ this.mColor = color;
+ return this;
+ }
+
+ public Builder setGearCount(int gearCount) {
+ this.mGearCount = gearCount;
+ return this;
+ }
+
+ public Builder setGearSwipeDegrees(@IntRange(from = 0, to = 360) int gearSwipeDegrees) {
+ this.mGearSwipeDegrees = gearSwipeDegrees;
+ return this;
+ }
+
+ public GearLoadingRenderer build() {
+ GearLoadingRenderer loadingRenderer = new GearLoadingRenderer(mContext);
+ loadingRenderer.apply(this);
+ return loadingRenderer;
+ }
}
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/LevelLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/LevelLoadingRenderer.java
index a38534e..208699f 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/LevelLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/LevelLoadingRenderer.java
@@ -9,8 +9,8 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.support.annotation.Size;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
-import android.util.DisplayMetrics;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
@@ -28,13 +28,10 @@ public class LevelLoadingRenderer extends LoadingRenderer {
private static final int NUM_POINTS = 5;
private static final int DEGREE_360 = 360;
- private static final float MIN_SWIPE_DEGREE = 0.1f;
private static final float MAX_SWIPE_DEGREES = 0.8f * DEGREE_360;
private static final float FULL_GROUP_ROTATION = 3.0f * DEGREE_360;
- private static final float MAX_ROTATION_INCREMENT = 0.25f * DEGREE_360;
- private static final float LEVEL2_SWEEP_ANGLE_OFFSET = 7.0f / 8.0f;
- private static final float LEVEL3_SWEEP_ANGLE_OFFSET = 5.0f / 8.0f;
+ private static final float[] LEVEL_SWEEP_ANGLE_OFFSETS = new float[]{1.0f, 7.0f / 8.0f, 5.0f / 8.0f};
private static final float START_TRIM_DURATION_OFFSET = 0.5f;
private static final float END_TRIM_DURATION_OFFSET = 1.0f;
@@ -42,7 +39,8 @@ public class LevelLoadingRenderer extends LoadingRenderer {
private static final float DEFAULT_CENTER_RADIUS = 12.5f;
private static final float DEFAULT_STROKE_WIDTH = 2.5f;
- private static final int DEFAULT_COLOR = Color.WHITE;
+ private static final int[] DEFAULT_LEVEL_COLORS = new int[]{Color.parseColor("#55ffffff"),
+ Color.parseColor("#b1ffffff"), Color.parseColor("#ffffffff")};
private final Paint mPaint = new Paint();
private final RectF mTempBounds = new RectF();
@@ -64,9 +62,10 @@ public void onAnimationStart(Animator animation) {
}
};
- private int mLevel1Color;
- private int mLevel2Color;
- private int mLevel3Color;
+ @Size(3)
+ private int[] mLevelColors;
+ @Size(3)
+ private float[] mLevelSwipeDegrees;
private float mStrokeInset;
@@ -75,189 +74,226 @@ public void onAnimationStart(Animator animation) {
private float mEndDegrees;
private float mStartDegrees;
- private float mLevel1SwipeDegrees;
- private float mLevel2SwipeDegrees;
- private float mLevel3SwipeDegrees;
- private float mRotationIncrement;
private float mOriginEndDegrees;
private float mOriginStartDegrees;
- private float mOriginRotationIncrement;
private float mStrokeWidth;
private float mCenterRadius;
- public LevelLoadingRenderer(Context context) {
+ private LevelLoadingRenderer(Context context) {
super(context);
init(context);
setupPaint();
addRenderListener(mAnimatorListener);
}
-
+
private void init(Context context) {
mStrokeWidth = DensityUtil.dip2px(context, DEFAULT_STROKE_WIDTH);
mCenterRadius = DensityUtil.dip2px(context, DEFAULT_CENTER_RADIUS);
+
+ mLevelSwipeDegrees = new float[3];
+ mLevelColors = DEFAULT_LEVEL_COLORS;
}
-
+
private void setupPaint() {
- mLevel1Color = oneThirdAlphaColor(DEFAULT_COLOR);
- mLevel2Color = twoThirdAlphaColor(DEFAULT_COLOR);
- mLevel3Color = DEFAULT_COLOR;
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(mStrokeWidth);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeCap(Paint.Cap.ROUND);
- setInsets((int) getWidth(), (int) getHeight());
+ initStrokeInset((int) mWidth, (int) mHeight);
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas) {
int saveCount = canvas.save();
- canvas.rotate(mGroupRotation, bounds.exactCenterX(), bounds.exactCenterY());
- RectF arcBounds = mTempBounds;
- arcBounds.set(bounds);
- arcBounds.inset(mStrokeInset, mStrokeInset);
+ mTempBounds.set(mBounds);
+ mTempBounds.inset(mStrokeInset, mStrokeInset);
+ canvas.rotate(mGroupRotation, mTempBounds.centerX(), mTempBounds.centerY());
- mPaint.setColor(mLevel1Color);
- canvas.drawArc(arcBounds, mEndDegrees, mLevel1SwipeDegrees, false, mPaint);
- mPaint.setColor(mLevel2Color);
- canvas.drawArc(arcBounds, mEndDegrees, mLevel2SwipeDegrees, false, mPaint);
- mPaint.setColor(mLevel3Color);
- canvas.drawArc(arcBounds, mEndDegrees, mLevel3SwipeDegrees, false, mPaint);
+ for (int i = 0; i < 3; i++) {
+ if (mLevelSwipeDegrees[i] != 0) {
+ mPaint.setColor(mLevelColors[i]);
+ canvas.drawArc(mTempBounds, mEndDegrees, mLevelSwipeDegrees[i], false, mPaint);
+ }
+ }
canvas.restoreToCount(saveCount);
}
@Override
- public void computeRender(float renderProgress) {
- // Moving the start trim only occurs in the first 50% of a
- // single ring animation
+ protected void computeRender(float renderProgress) {
+ // Moving the start trim only occurs in the first 50% of a single ring animation
if (renderProgress <= START_TRIM_DURATION_OFFSET) {
float startTrimProgress = (renderProgress) / START_TRIM_DURATION_OFFSET;
mStartDegrees = mOriginStartDegrees + MAX_SWIPE_DEGREES * MATERIAL_INTERPOLATOR.getInterpolation(startTrimProgress);
- float mSwipeDegrees = MIN_SWIPE_DEGREE;
- if (Math.abs(mEndDegrees - mStartDegrees) > MIN_SWIPE_DEGREE) {
- mSwipeDegrees = mEndDegrees - mStartDegrees;
- }
+ float mSwipeDegrees = mEndDegrees - mStartDegrees;
float levelSwipeDegreesProgress = Math.abs(mSwipeDegrees) / MAX_SWIPE_DEGREES;
float level1Increment = DECELERATE_INTERPOLATOR.getInterpolation(levelSwipeDegreesProgress) - LINEAR_INTERPOLATOR.getInterpolation(levelSwipeDegreesProgress);
float level3Increment = ACCELERATE_INTERPOLATOR.getInterpolation(levelSwipeDegreesProgress) - LINEAR_INTERPOLATOR.getInterpolation(levelSwipeDegreesProgress);
- mLevel1SwipeDegrees = -mSwipeDegrees * (1 + level1Increment);
- mLevel2SwipeDegrees = -mSwipeDegrees * LEVEL2_SWEEP_ANGLE_OFFSET;
- mLevel3SwipeDegrees = -mSwipeDegrees * LEVEL3_SWEEP_ANGLE_OFFSET * (1 + level3Increment);
+ mLevelSwipeDegrees[0] = -mSwipeDegrees * LEVEL_SWEEP_ANGLE_OFFSETS[0] * (1.0f + level1Increment);
+ mLevelSwipeDegrees[1] = -mSwipeDegrees * LEVEL_SWEEP_ANGLE_OFFSETS[1] * 1.0f;
+ mLevelSwipeDegrees[2] = -mSwipeDegrees * LEVEL_SWEEP_ANGLE_OFFSETS[2] * (1.0f + level3Increment);
}
- // Moving the end trim starts after 50% of a single ring
- // animation completes
+ // Moving the end trim starts after 50% of a single ring animation
if (renderProgress > START_TRIM_DURATION_OFFSET) {
float endTrimProgress = (renderProgress - START_TRIM_DURATION_OFFSET) / (END_TRIM_DURATION_OFFSET - START_TRIM_DURATION_OFFSET);
mEndDegrees = mOriginEndDegrees + MAX_SWIPE_DEGREES * MATERIAL_INTERPOLATOR.getInterpolation(endTrimProgress);
- float mSwipeDegrees = MIN_SWIPE_DEGREE;
- if (Math.abs(mEndDegrees - mStartDegrees) > MIN_SWIPE_DEGREE) {
- mSwipeDegrees = mEndDegrees - mStartDegrees;
- }
+ float mSwipeDegrees = mEndDegrees - mStartDegrees;
float levelSwipeDegreesProgress = Math.abs(mSwipeDegrees) / MAX_SWIPE_DEGREES;
- if (levelSwipeDegreesProgress > LEVEL2_SWEEP_ANGLE_OFFSET) {
- mLevel1SwipeDegrees = -mSwipeDegrees;
- mLevel2SwipeDegrees = MAX_SWIPE_DEGREES * LEVEL2_SWEEP_ANGLE_OFFSET;
- mLevel3SwipeDegrees = MAX_SWIPE_DEGREES * LEVEL3_SWEEP_ANGLE_OFFSET;
- } else if (levelSwipeDegreesProgress > LEVEL3_SWEEP_ANGLE_OFFSET) {
- mLevel1SwipeDegrees = MIN_SWIPE_DEGREE;
- mLevel2SwipeDegrees = -mSwipeDegrees;
- mLevel3SwipeDegrees = MAX_SWIPE_DEGREES * LEVEL3_SWEEP_ANGLE_OFFSET;
+ if (levelSwipeDegreesProgress > LEVEL_SWEEP_ANGLE_OFFSETS[1]) {
+ mLevelSwipeDegrees[0] = -mSwipeDegrees;
+ mLevelSwipeDegrees[1] = MAX_SWIPE_DEGREES * LEVEL_SWEEP_ANGLE_OFFSETS[1];
+ mLevelSwipeDegrees[2] = MAX_SWIPE_DEGREES * LEVEL_SWEEP_ANGLE_OFFSETS[2];
+ } else if (levelSwipeDegreesProgress > LEVEL_SWEEP_ANGLE_OFFSETS[2]) {
+ mLevelSwipeDegrees[0] = 0;
+ mLevelSwipeDegrees[1] = -mSwipeDegrees;
+ mLevelSwipeDegrees[2] = MAX_SWIPE_DEGREES * LEVEL_SWEEP_ANGLE_OFFSETS[2];
} else {
- mLevel1SwipeDegrees = MIN_SWIPE_DEGREE;
- mLevel2SwipeDegrees = MIN_SWIPE_DEGREE;
- mLevel3SwipeDegrees = -mSwipeDegrees;
+ mLevelSwipeDegrees[0] = 0;
+ mLevelSwipeDegrees[1] = 0;
+ mLevelSwipeDegrees[2] = -mSwipeDegrees;
}
}
mGroupRotation = ((FULL_GROUP_ROTATION / NUM_POINTS) * renderProgress) + (FULL_GROUP_ROTATION * (mRotationCount / NUM_POINTS));
- mRotationIncrement = mOriginRotationIncrement + (MAX_ROTATION_INCREMENT * renderProgress);
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
}
@Override
- public void reset() {
+ protected void reset() {
resetOriginals();
}
- public void setColor(int color) {
- mLevel1Color = oneThirdAlphaColor(color);
- mLevel2Color = twoThirdAlphaColor(color);
- mLevel3Color = color;
- }
-
- public void setInsets(int width, int height) {
- final float minEdge = (float) Math.min(width, height);
- float insets;
- if (mCenterRadius <= 0 || minEdge < 0) {
- insets = (float) Math.ceil(mStrokeWidth / 2.0f);
- } else {
- insets = minEdge / 2.0f - mCenterRadius;
- }
- mStrokeInset = insets;
+ private void initStrokeInset(float width, float height) {
+ float minSize = Math.min(width, height);
+ float strokeInset = minSize / 2.0f - mCenterRadius;
+ float minStrokeInset = (float) Math.ceil(mStrokeWidth / 2.0f);
+ mStrokeInset = strokeInset < minStrokeInset ? minStrokeInset : strokeInset;
}
private void storeOriginals() {
mOriginEndDegrees = mEndDegrees;
- mOriginStartDegrees = mStartDegrees;
- mOriginRotationIncrement = mRotationIncrement;
+ mOriginStartDegrees = mEndDegrees;
}
private void resetOriginals() {
mOriginEndDegrees = 0;
mOriginStartDegrees = 0;
- mOriginRotationIncrement = 0;
mEndDegrees = 0;
mStartDegrees = 0;
- mRotationIncrement = 0;
- mLevel1SwipeDegrees = MIN_SWIPE_DEGREE;
- mLevel2SwipeDegrees = MIN_SWIPE_DEGREE;
- mLevel3SwipeDegrees = MIN_SWIPE_DEGREE;
+ mLevelSwipeDegrees[0] = 0;
+ mLevelSwipeDegrees[1] = 0;
+ mLevelSwipeDegrees[2] = 0;
}
- private int oneThirdAlphaColor(int colorValue) {
- int startA = (colorValue >> 24) & 0xff;
- int startR = (colorValue >> 16) & 0xff;
- int startG = (colorValue >> 8) & 0xff;
- int startB = colorValue & 0xff;
+ private void apply(Builder builder) {
+ this.mWidth = builder.mWidth > 0 ? builder.mWidth : this.mWidth;
+ this.mHeight = builder.mHeight > 0 ? builder.mHeight : this.mHeight;
+ this.mStrokeWidth = builder.mStrokeWidth > 0 ? builder.mStrokeWidth : this.mStrokeWidth;
+ this.mCenterRadius = builder.mCenterRadius > 0 ? builder.mCenterRadius : this.mCenterRadius;
- return (startA / 3 << 24)
- | (startR << 16)
- | (startG << 8)
- | startB;
+ this.mDuration = builder.mDuration > 0 ? builder.mDuration : this.mDuration;
+
+ this.mLevelColors = builder.mLevelColors != null ? builder.mLevelColors : this.mLevelColors;
+
+ setupPaint();
+ initStrokeInset(this.mWidth, this.mHeight);
}
- private int twoThirdAlphaColor(int colorValue) {
- int startA = (colorValue >> 24) & 0xff;
- int startR = (colorValue >> 16) & 0xff;
- int startG = (colorValue >> 8) & 0xff;
- int startB = colorValue & 0xff;
+ public static class Builder {
+ private Context mContext;
+
+ private int mWidth;
+ private int mHeight;
+ private int mStrokeWidth;
+ private int mCenterRadius;
+
+ private int mDuration;
+
+ @Size(3)
+ private int[] mLevelColors;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public Builder setWidth(int width) {
+ this.mWidth = width;
+ return this;
+ }
+
+ public Builder setHeight(int height) {
+ this.mHeight = height;
+ return this;
+ }
+
+ public Builder setStrokeWidth(int strokeWidth) {
+ this.mStrokeWidth = strokeWidth;
+ return this;
+ }
+
+ public Builder setCenterRadius(int centerRadius) {
+ this.mCenterRadius = centerRadius;
+ return this;
+ }
+
+ public Builder setDuration(int duration) {
+ this.mDuration = duration;
+ return this;
+ }
+
+ public Builder setLevelColors(@Size(3) int[] colors) {
+ this.mLevelColors = colors;
+ return this;
+ }
+
+ public Builder setLevelColor(int color) {
+ return setLevelColors(new int[]{oneThirdAlphaColor(color), twoThirdAlphaColor(color), color});
+ }
+
+ public LevelLoadingRenderer build() {
+ LevelLoadingRenderer loadingRenderer = new LevelLoadingRenderer(mContext);
+ loadingRenderer.apply(this);
+ return loadingRenderer;
+ }
+
+ private int oneThirdAlphaColor(int colorValue) {
+ int startA = (colorValue >> 24) & 0xff;
+ int startR = (colorValue >> 16) & 0xff;
+ int startG = (colorValue >> 8) & 0xff;
+ int startB = colorValue & 0xff;
- return (startA * 2 / 3 << 24)
- | (startR << 16)
- | (startG << 8)
- | startB;
+ return (startA / 3 << 24) | (startR << 16) | (startG << 8) | startB;
+ }
+
+ private int twoThirdAlphaColor(int colorValue) {
+ int startA = (colorValue >> 24) & 0xff;
+ int startR = (colorValue >> 16) & 0xff;
+ int startG = (colorValue >> 8) & 0xff;
+ int startB = colorValue & 0xff;
+
+ return (startA * 2 / 3 << 24) | (startR << 16) | (startG << 8) | startB;
+ }
}
+
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/MaterialLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/MaterialLoadingRenderer.java
index f4ebc8f..5f87f9d 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/MaterialLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/MaterialLoadingRenderer.java
@@ -7,11 +7,8 @@
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
-import android.graphics.Rect;
import android.graphics.RectF;
-import android.support.annotation.NonNull;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
-import android.util.DisplayMetrics;
import android.view.animation.Interpolator;
import app.dinus.com.loadingdrawable.DensityUtil;
@@ -23,15 +20,13 @@ public class MaterialLoadingRenderer extends LoadingRenderer {
private static final int DEGREE_360 = 360;
private static final int NUM_POINTS = 5;
- private static final float MIN_SWIPE_DEGREE = 0.1f;
private static final float MAX_SWIPE_DEGREES = 0.8f * DEGREE_360;
private static final float FULL_GROUP_ROTATION = 3.0f * DEGREE_360;
- private static final float MAX_ROTATION_INCREMENT = 0.25f * DEGREE_360;
private static final float COLOR_START_DELAY_OFFSET = 0.8f;
private static final float END_TRIM_DURATION_OFFSET = 1.0f;
private static final float START_TRIM_DURATION_OFFSET = 0.5f;
-
+
private static final float DEFAULT_CENTER_RADIUS = 12.5f;
private static final float DEFAULT_STROKE_WIDTH = 2.5f;
@@ -72,15 +67,13 @@ public void onAnimationStart(Animator animation) {
private float mEndDegrees;
private float mStartDegrees;
private float mSwipeDegrees;
- private float mRotationIncrement;
private float mOriginEndDegrees;
private float mOriginStartDegrees;
- private float mOriginRotationIncrement;
private float mStrokeWidth;
private float mCenterRadius;
- public MaterialLoadingRenderer(Context context) {
+ private MaterialLoadingRenderer(Context context) {
super(context);
init(context);
setupPaint();
@@ -94,7 +87,7 @@ private void init(Context context) {
mColors = DEFAULT_COLORS;
setColorIndex(0);
- setInsets((int) getWidth(), (int) getHeight());
+ initStrokeInset(mWidth, mHeight);
}
private void setupPaint() {
@@ -105,70 +98,65 @@ private void setupPaint() {
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas) {
int saveCount = canvas.save();
- canvas.rotate(mGroupRotation, bounds.exactCenterX(), bounds.exactCenterY());
+ mTempBounds.set(mBounds);
+ mTempBounds.inset(mStrokeInset, mStrokeInset);
- RectF arcBounds = mTempBounds;
- arcBounds.set(bounds);
- arcBounds.inset(mStrokeInset, mStrokeInset);
+ canvas.rotate(mGroupRotation, mTempBounds.centerX(), mTempBounds.centerY());
- mPaint.setColor(mCurrentColor);
- canvas.drawArc(arcBounds, mStartDegrees, mSwipeDegrees, false, mPaint);
+ if (mSwipeDegrees != 0) {
+ mPaint.setColor(mCurrentColor);
+ canvas.drawArc(mTempBounds, mStartDegrees, mSwipeDegrees, false, mPaint);
+ }
canvas.restoreToCount(saveCount);
}
@Override
- public void computeRender(float renderProgress) {
+ protected void computeRender(float renderProgress) {
updateRingColor(renderProgress);
- // Moving the start trim only occurs in the first 50% of a
- // single ring animation
+ // Moving the start trim only occurs in the first 50% of a single ring animation
if (renderProgress <= START_TRIM_DURATION_OFFSET) {
float startTrimProgress = renderProgress / START_TRIM_DURATION_OFFSET;
- mStartDegrees = mOriginStartDegrees + MAX_SWIPE_DEGREES * MATERIAL_INTERPOLATOR.getInterpolation(startTrimProgress);
+ mStartDegrees = mOriginStartDegrees + MAX_SWIPE_DEGREES
+ * MATERIAL_INTERPOLATOR.getInterpolation(startTrimProgress);
}
- // Moving the end trim starts after 50% of a single ring
- // animation completes
+ // Moving the end trim starts after 50% of a single ring animation completes
if (renderProgress > START_TRIM_DURATION_OFFSET) {
- float endTrimProgress = (renderProgress - START_TRIM_DURATION_OFFSET) / (END_TRIM_DURATION_OFFSET - START_TRIM_DURATION_OFFSET);
- mEndDegrees = mOriginEndDegrees + MAX_SWIPE_DEGREES * MATERIAL_INTERPOLATOR.getInterpolation(endTrimProgress);
+ float endTrimProgress = (renderProgress - START_TRIM_DURATION_OFFSET)
+ / (END_TRIM_DURATION_OFFSET - START_TRIM_DURATION_OFFSET);
+ mEndDegrees = mOriginEndDegrees + MAX_SWIPE_DEGREES
+ * MATERIAL_INTERPOLATOR.getInterpolation(endTrimProgress);
}
- if (Math.abs(mEndDegrees - mStartDegrees) > MIN_SWIPE_DEGREE) {
+ if (Math.abs(mEndDegrees - mStartDegrees) > 0) {
mSwipeDegrees = mEndDegrees - mStartDegrees;
}
- mGroupRotation = ((FULL_GROUP_ROTATION / NUM_POINTS) * renderProgress) + (FULL_GROUP_ROTATION * (mRotationCount / NUM_POINTS));
- mRotationIncrement = mOriginRotationIncrement + (MAX_ROTATION_INCREMENT * renderProgress);
+ mGroupRotation = ((FULL_GROUP_ROTATION / NUM_POINTS) * renderProgress)
+ + (FULL_GROUP_ROTATION * (mRotationCount / NUM_POINTS));
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
}
@Override
- public void reset() {
+ protected void reset() {
resetOriginals();
}
- public void setColors(@NonNull int[] colors) {
- mColors = colors;
- setColorIndex(0);
- }
-
- public void setColorIndex(int index) {
+ private void setColorIndex(int index) {
mColorIndex = index;
mCurrentColor = mColors[mColorIndex];
}
@@ -185,33 +173,24 @@ private void goToNextColor() {
setColorIndex(getNextColorIndex());
}
- private void setInsets(int width, int height) {
- final float minEdge = (float) Math.min(width, height);
- float insets;
- if (mCenterRadius <= 0 || minEdge < 0) {
- insets = (float) Math.ceil(mStrokeWidth / 2.0f);
- } else {
- insets = minEdge / 2.0f - mCenterRadius;
- }
- mStrokeInset = insets;
+ private void initStrokeInset(float width, float height) {
+ float minSize = Math.min(width, height);
+ float strokeInset = minSize / 2.0f - mCenterRadius;
+ float minStrokeInset = (float) Math.ceil(mStrokeWidth / 2.0f);
+ mStrokeInset = strokeInset < minStrokeInset ? minStrokeInset : strokeInset;
}
private void storeOriginals() {
mOriginEndDegrees = mEndDegrees;
- mOriginStartDegrees = mStartDegrees;
- mOriginRotationIncrement = mRotationIncrement;
+ mOriginStartDegrees = mEndDegrees;
}
private void resetOriginals() {
mOriginEndDegrees = 0;
mOriginStartDegrees = 0;
- mOriginRotationIncrement = 0;
mEndDegrees = 0;
mStartDegrees = 0;
- mRotationIncrement = 0;
-
- mSwipeDegrees = MIN_SWIPE_DEGREE;
}
private int getStartingColor() {
@@ -242,8 +221,71 @@ private int evaluateColorChange(float fraction, int startValue, int endValue) {
| ((startB + (int) (fraction * (endB - startB))));
}
+ private void apply(Builder builder) {
+ this.mWidth = builder.mWidth > 0 ? builder.mWidth : this.mWidth;
+ this.mHeight = builder.mHeight > 0 ? builder.mHeight : this.mHeight;
+ this.mStrokeWidth = builder.mStrokeWidth > 0 ? builder.mStrokeWidth : this.mStrokeWidth;
+ this.mCenterRadius = builder.mCenterRadius > 0 ? builder.mCenterRadius : this.mCenterRadius;
+
+ this.mDuration = builder.mDuration > 0 ? builder.mDuration : this.mDuration;
+
+ this.mColors = builder.mColors != null && builder.mColors.length > 0 ? builder.mColors : this.mColors;
+
+ setColorIndex(0);
+ setupPaint();
+ initStrokeInset(this.mWidth, this.mHeight);
+ }
+
public static class Builder {
+ private Context mContext;
+
+ private int mWidth;
+ private int mHeight;
+ private int mStrokeWidth;
+ private int mCenterRadius;
+
+ private int mDuration;
+ private int[] mColors;
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public Builder setWidth(int width) {
+ this.mWidth = width;
+ return this;
+ }
+
+ public Builder setHeight(int height) {
+ this.mHeight = height;
+ return this;
+ }
+
+ public Builder setStrokeWidth(int strokeWidth) {
+ this.mStrokeWidth = strokeWidth;
+ return this;
+ }
+
+ public Builder setCenterRadius(int centerRadius) {
+ this.mCenterRadius = centerRadius;
+ return this;
+ }
+
+ public Builder setDuration(int duration) {
+ this.mDuration = duration;
+ return this;
+ }
+
+ public Builder setColors(int[] colors) {
+ this.mColors = colors;
+ return this;
+ }
+
+ public MaterialLoadingRenderer build() {
+ MaterialLoadingRenderer loadingRenderer = new MaterialLoadingRenderer(mContext);
+ loadingRenderer.apply(this);
+ return loadingRenderer;
+ }
}
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/WhorlLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/WhorlLoadingRenderer.java
index eecb02c..827ce2b 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/WhorlLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/circle/rotate/WhorlLoadingRenderer.java
@@ -23,10 +23,8 @@ public class WhorlLoadingRenderer extends LoadingRenderer {
private static final int DEGREE_360 = 360;
private static final int NUM_POINTS = 5;
- private static final float MIN_SWIPE_DEGREE = 0.1f;
private static final float MAX_SWIPE_DEGREES = 0.6f * DEGREE_360;
private static final float FULL_GROUP_ROTATION = 3.0f * DEGREE_360;
- private static final float MAX_ROTATION_INCREMENT = 0.25f * DEGREE_360;
private static final float START_TRIM_DURATION_OFFSET = 0.5f;
private static final float END_TRIM_DURATION_OFFSET = 1.0f;
@@ -40,6 +38,7 @@ public class WhorlLoadingRenderer extends LoadingRenderer {
private final Paint mPaint = new Paint();
private final RectF mTempBounds = new RectF();
+ private final RectF mTempArcBounds = new RectF();
private final Animator.AnimatorListener mAnimatorListener = new AnimatorListenerAdapter() {
@Override
@@ -68,15 +67,13 @@ public void onAnimationStart(Animator animation) {
private float mEndDegrees;
private float mStartDegrees;
private float mSwipeDegrees;
- private float mRotationIncrement;
private float mOriginEndDegrees;
private float mOriginStartDegrees;
- private float mOriginRotationIncrement;
-
+
private float mStrokeWidth;
private float mCenterRadius;
- public WhorlLoadingRenderer(Context context) {
+ private WhorlLoadingRenderer(Context context) {
super(context);
init(context);
setupPaint();
@@ -87,7 +84,8 @@ private void init(Context context) {
mColors = DEFAULT_COLORS;
mStrokeWidth = DensityUtil.dip2px(context, DEFAULT_STROKE_WIDTH);
mCenterRadius = DensityUtil.dip2px(context, DEFAULT_CENTER_RADIUS);
- setInsets((int) getWidth(), (int) getHeight());
+
+ initStrokeInset(mWidth, mHeight);
}
private void setupPaint() {
@@ -98,26 +96,27 @@ private void setupPaint() {
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas) {
int saveCount = canvas.save();
- canvas.rotate(mGroupRotation, bounds.exactCenterX(), bounds.exactCenterY());
- RectF arcBounds = mTempBounds;
- arcBounds.set(bounds);
- arcBounds.inset(mStrokeInset, mStrokeInset);
+ mTempBounds.set(mBounds);
+ mTempBounds.inset(mStrokeInset, mStrokeInset);
+
+ canvas.rotate(mGroupRotation, mTempBounds.centerX(), mTempBounds.centerY());
- for (int i = 0; i < mColors.length; i++) {
- mPaint.setStrokeWidth(mStrokeWidth / (i + 1));
- mPaint.setColor(mColors[i]);
- canvas.drawArc(createArcBounds(arcBounds, i), mStartDegrees + DEGREE_180 * (i % 2),
- mSwipeDegrees, false, mPaint);
+ if (mSwipeDegrees != 0) {
+ for (int i = 0; i < mColors.length; i++) {
+ mPaint.setStrokeWidth(mStrokeWidth / (i + 1));
+ mPaint.setColor(mColors[i]);
+ canvas.drawArc(createArcBounds(mTempBounds, i), mStartDegrees + DEGREE_180 * (i % 2),
+ mSwipeDegrees, false, mPaint);
+ }
}
canvas.restoreToCount(saveCount);
}
private RectF createArcBounds(RectF sourceArcBounds, int index) {
- RectF arcBounds = new RectF();
int intervalWidth = 0;
for (int i = 0; i < index; i++) {
@@ -128,82 +127,135 @@ private RectF createArcBounds(RectF sourceArcBounds, int index) {
int arcBoundsTop = (int) (sourceArcBounds.top + intervalWidth);
int arcBoundsRight = (int) (sourceArcBounds.right - intervalWidth);
int arcBoundsBottom = (int) (sourceArcBounds.bottom - intervalWidth);
- arcBounds.set(arcBoundsLeft, arcBoundsTop, arcBoundsRight, arcBoundsBottom);
+ mTempArcBounds.set(arcBoundsLeft, arcBoundsTop, arcBoundsRight, arcBoundsBottom);
- return arcBounds;
+ return mTempArcBounds;
}
@Override
- public void computeRender(float renderProgress) {
- // Moving the start trim only occurs in the first 50% of a
- // single ring animation
+ protected void computeRender(float renderProgress) {
+ // Moving the start trim only occurs in the first 50% of a single ring animation
if (renderProgress <= START_TRIM_DURATION_OFFSET) {
float startTrimProgress = (renderProgress) / (1.0f - START_TRIM_DURATION_OFFSET);
mStartDegrees = mOriginStartDegrees + MAX_SWIPE_DEGREES * MATERIAL_INTERPOLATOR.getInterpolation(startTrimProgress);
}
- // Moving the end trim starts after 50% of a single ring
- // animation completes
+ // Moving the end trim starts after 50% of a single ring animation
if (renderProgress > START_TRIM_DURATION_OFFSET) {
float endTrimProgress = (renderProgress - START_TRIM_DURATION_OFFSET) / (END_TRIM_DURATION_OFFSET - START_TRIM_DURATION_OFFSET);
mEndDegrees = mOriginEndDegrees + MAX_SWIPE_DEGREES * MATERIAL_INTERPOLATOR.getInterpolation(endTrimProgress);
}
- if (Math.abs(mEndDegrees - mStartDegrees) > MIN_SWIPE_DEGREE) {
+ if (Math.abs(mEndDegrees - mStartDegrees) > 0) {
mSwipeDegrees = mEndDegrees - mStartDegrees;
}
mGroupRotation = ((FULL_GROUP_ROTATION / NUM_POINTS) * renderProgress) + (FULL_GROUP_ROTATION * (mRotationCount / NUM_POINTS));
- mRotationIncrement = mOriginRotationIncrement + (MAX_ROTATION_INCREMENT * renderProgress);
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
+
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
+
}
@Override
- public void reset() {
+ protected void reset() {
resetOriginals();
}
- public void setColors(@NonNull int[] colors) {
- mColors = colors;
- }
-
- public void setInsets(int width, int height) {
- final float minEdge = (float) Math.min(width, height);
- float insets;
- if (mCenterRadius <= 0 || minEdge < 0) {
- insets = (float) Math.ceil(mStrokeWidth / 2.0f);
- } else {
- insets = minEdge / 2.0f - mCenterRadius;
- }
- mStrokeInset = insets;
+ private void initStrokeInset(float width, float height) {
+ float minSize = Math.min(width, height);
+ float strokeInset = minSize / 2.0f - mCenterRadius;
+ float minStrokeInset = (float) Math.ceil(mStrokeWidth / 2.0f);
+ mStrokeInset = strokeInset < minStrokeInset ? minStrokeInset : strokeInset;
}
private void storeOriginals() {
mOriginEndDegrees = mEndDegrees;
- mOriginStartDegrees = mStartDegrees;
- mOriginRotationIncrement = mRotationIncrement;
+ mOriginStartDegrees = mEndDegrees;
}
private void resetOriginals() {
mOriginEndDegrees = 0;
mOriginStartDegrees = 0;
- mOriginRotationIncrement = 0;
mEndDegrees = 0;
mStartDegrees = 0;
- mRotationIncrement = 0;
- mSwipeDegrees = MIN_SWIPE_DEGREE;
+ mSwipeDegrees = 0;
+ }
+
+ private void apply(Builder builder) {
+ this.mWidth = builder.mWidth > 0 ? builder.mWidth : this.mWidth;
+ this.mHeight = builder.mHeight > 0 ? builder.mHeight : this.mHeight;
+ this.mStrokeWidth = builder.mStrokeWidth > 0 ? builder.mStrokeWidth : this.mStrokeWidth;
+ this.mCenterRadius = builder.mCenterRadius > 0 ? builder.mCenterRadius : this.mCenterRadius;
+
+ this.mDuration = builder.mDuration > 0 ? builder.mDuration : this.mDuration;
+
+ this.mColors = builder.mColors != null && builder.mColors.length > 0 ? builder.mColors : this.mColors;
+
+ setupPaint();
+ initStrokeInset(this.mWidth, this.mHeight);
+ }
+
+ public static class Builder {
+ private Context mContext;
+
+ private int mWidth;
+ private int mHeight;
+ private int mStrokeWidth;
+ private int mCenterRadius;
+
+ private int mDuration;
+
+ private int[] mColors;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public Builder setWidth(int width) {
+ this.mWidth = width;
+ return this;
+ }
+
+ public Builder setHeight(int height) {
+ this.mHeight = height;
+ return this;
+ }
+
+ public Builder setStrokeWidth(int strokeWidth) {
+ this.mStrokeWidth = strokeWidth;
+ return this;
+ }
+
+ public Builder setCenterRadius(int centerRadius) {
+ this.mCenterRadius = centerRadius;
+ return this;
+ }
+
+ public Builder setDuration(int duration) {
+ this.mDuration = duration;
+ return this;
+ }
+
+ public Builder setColors(int[] colors) {
+ this.mColors = colors;
+ return this;
+ }
+
+ public WhorlLoadingRenderer build() {
+ WhorlLoadingRenderer loadingRenderer = new WhorlLoadingRenderer(mContext);
+ loadingRenderer.apply(this);
+ return loadingRenderer;
+ }
}
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/goods/BalloonLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/goods/BalloonLoadingRenderer.java
index 283f69e..269ecac 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/goods/BalloonLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/goods/BalloonLoadingRenderer.java
@@ -78,7 +78,7 @@ public class BalloonLoadingRenderer extends LoadingRenderer {
private int mCannulaColor;
private int mPipeBodyColor;
- public BalloonLoadingRenderer(Context context) {
+ private BalloonLoadingRenderer(Context context) {
super(context);
init(context);
setupPaint();
@@ -110,7 +110,7 @@ private void init(Context context) {
mProgressText = 10 + PERCENT_SIGN;
- setDuration(ANIMATION_DURATION);
+ mDuration = ANIMATION_DURATION;
}
private void setupPaint() {
@@ -119,7 +119,7 @@ private void setupPaint() {
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas, Rect bounds) {
int saveCount = canvas.save();
RectF arcBounds = mCurrentBounds;
@@ -160,7 +160,7 @@ public void draw(Canvas canvas, Rect bounds) {
}
@Override
- public void computeRender(float renderProgress) {
+ protected void computeRender(float renderProgress) {
RectF arcBounds = mCurrentBounds;
//compute gas tube bounds
mGasTubeBounds.set(arcBounds.centerX() - mGasTubeWidth / 2.0f, arcBounds.centerY(),
@@ -282,18 +282,30 @@ private Path createBalloonPath(RectF balloonRect, float progress) {
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
+
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
}
@Override
- public void reset() {
+ protected void reset() {
+ }
+
+ public static class Builder {
+ private Context mContext;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public BalloonLoadingRenderer build() {
+ BalloonLoadingRenderer loadingRenderer = new BalloonLoadingRenderer(mContext);
+ return loadingRenderer;
+ }
}
}
\ No newline at end of file
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/goods/WaterBottleLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/goods/WaterBottleLoadingRenderer.java
index 92ebe92..5f86023 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/goods/WaterBottleLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/goods/WaterBottleLoadingRenderer.java
@@ -66,7 +66,7 @@ public class WaterBottleLoadingRenderer extends LoadingRenderer {
private int mWaveCount;
- public WaterBottleLoadingRenderer(Context context) {
+ private WaterBottleLoadingRenderer(Context context) {
super(context);
init(context);
setupPaint();
@@ -88,7 +88,7 @@ private void init(Context context) {
mWaveCount = DEFAULT_WAVE_COUNT;
- setDuration(ANIMATION_DURATION);
+ mDuration = ANIMATION_DURATION;
}
private void setupPaint() {
@@ -98,7 +98,7 @@ private void setupPaint() {
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas, Rect bounds) {
int saveCount = canvas.save();
RectF arcBounds = mCurrentBounds;
@@ -130,7 +130,7 @@ public void draw(Canvas canvas, Rect bounds) {
}
@Override
- public void computeRender(float renderProgress) {
+ protected void computeRender(float renderProgress) {
if (mCurrentBounds.width() <= 0) {
return;
}
@@ -278,19 +278,19 @@ private float getMaxRiseHeight(float bottleRadius, float waterDropRadius, float
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
+
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
+
}
@Override
- public void reset() {
+ protected void reset() {
}
private class WaterDropHolder {
@@ -306,4 +306,17 @@ private class WaterDropHolder {
public boolean mNeedDraw;
}
+
+ public static class Builder {
+ private Context mContext;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public WaterBottleLoadingRenderer build() {
+ WaterBottleLoadingRenderer loadingRenderer = new WaterBottleLoadingRenderer(mContext);
+ return loadingRenderer;
+ }
+ }
}
\ No newline at end of file
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/scenery/DayNightLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/scenery/DayNightLoadingRenderer.java
index 42b9406..cf5d319 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/scenery/DayNightLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/scenery/DayNightLoadingRenderer.java
@@ -109,7 +109,7 @@ public void onAnimationRepeat(Animator animator) {
private int mSunRayCount;
- public DayNightLoadingRenderer(Context context) {
+ private DayNightLoadingRenderer(Context context) {
super(context);
init(context);
setupPaint();
@@ -140,7 +140,7 @@ private void init(Context context) {
mCurrentColor = DEFAULT_COLOR;
- setDuration(ANIMATION_DURATION);
+ mDuration = ANIMATION_DURATION;
}
private void setupPaint() {
@@ -152,7 +152,7 @@ private void setupPaint() {
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas, Rect bounds) {
int saveCount = canvas.save();
RectF arcBounds = mTempBounds;
@@ -201,7 +201,7 @@ public void draw(Canvas canvas, Rect bounds) {
}
@Override
- public void computeRender(float renderProgress) {
+ protected void computeRender(float renderProgress) {
if (renderProgress <= SUN_RISE_DURATION_OFFSET) {
float sunRiseProgress = renderProgress / SUN_RISE_DURATION_OFFSET;
mSunCoordinateY = mInitSun$MoonCoordinateY - mMaxSun$MoonRiseDistance * MATERIAL_INTERPOLATOR.getInterpolation(sunRiseProgress);
@@ -273,19 +273,19 @@ public void computeRender(float renderProgress) {
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
+
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
+
}
@Override
- public void reset() {
+ protected void reset() {
}
private void initStarHolders(RectF currentBounds) {
@@ -344,4 +344,17 @@ public StarHolder(float flashOffset, PointF mPoint) {
this.mInterpolator = INTERPOLATORS[mRandom.nextInt(INTERPOLATORS.length)];
}
}
+
+ public static class Builder {
+ private Context mContext;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public DayNightLoadingRenderer build() {
+ DayNightLoadingRenderer loadingRenderer = new DayNightLoadingRenderer(mContext);
+ return loadingRenderer;
+ }
+ }
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/scenery/ElectricFanLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/scenery/ElectricFanLoadingRenderer.java
index e325b3b..63c8fd8 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/scenery/ElectricFanLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/scenery/ElectricFanLoadingRenderer.java
@@ -120,7 +120,7 @@ public void onAnimationRepeat(Animator animator) {
private Drawable mLoadingDrawable;
private Drawable mElectricFanDrawable;
- public ElectricFanLoadingRenderer(Context context) {
+ private ElectricFanLoadingRenderer(Context context) {
super(context);
init(context);
setupPaint();
@@ -146,8 +146,8 @@ private void init(Context context) {
mLoadingDrawable = context.getResources().getDrawable(R.drawable.ic_loading);
mElectricFanDrawable = context.getResources().getDrawable(R.drawable.ic_eletric_fan);
- setDuration(ANIMATION_DURATION);
- setInsets((int) getWidth(), (int) getHeight());
+ mDuration = ANIMATION_DURATION;
+ setInsets((int) mWidth, (int) mHeight);
}
private void setupPaint() {
@@ -158,7 +158,7 @@ private void setupPaint() {
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas, Rect bounds) {
int saveCount = canvas.save();
RectF arcBounds = mTempBounds;
@@ -296,7 +296,7 @@ private Path createProgressPath(float progress, float circleRadius, RectF progre
}
@Override
- public void computeRender(float renderProgress) {
+ protected void computeRender(float renderProgress) {
if (renderProgress < DECELERATE_DURATION_PERCENTAGE) {
mProgress = DECELERATE_INTERPOLATOR.getInterpolation(renderProgress / DECELERATE_DURATION_PERCENTAGE) * DECELERATE_DURATION_PERCENTAGE;
} else {
@@ -305,26 +305,26 @@ public void computeRender(float renderProgress) {
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
+
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
+
}
@Override
- public void reset() {
+ protected void reset() {
mScale = 1.0f;
mCurrentLeafCount = 0;
mNextLeafCreateThreshold = 0.0f;
mLeafHolders.clear();
}
- public void setInsets(int width, int height) {
+ protected void setInsets(int width, int height) {
final float minEdge = (float) Math.min(width, height);
float insetXs;
if (mCenterRadius <= 0 || minEdge < 0) {
@@ -374,7 +374,7 @@ private ValueAnimator getBezierValueAnimator(LeafHolder target, RectF leafFlyRec
animator.addUpdateListener(new BezierListener(target));
animator.setTarget(target);
- animator.setDuration((long) ((mRandom.nextInt(300) + getDuration() * DEFAULT_LEAF_FLY_DURATION_FACTOR) * (1.0f - progress)));
+ animator.setDuration((long) ((mRandom.nextInt(300) + mDuration * DEFAULT_LEAF_FLY_DURATION_FACTOR) * (1.0f - progress)));
return animator;
}
@@ -395,10 +395,6 @@ private PointF getPoint2(RectF leafFlyRect) {
return point;
}
- public void setMode(@MODE int mode) {
- this.mMode = mode;
- }
-
private class BezierEvaluator implements TypeEvaluator {
private PointF point1;
@@ -461,4 +457,17 @@ private class LeafHolder {
public float mMaxRotation = mRandom.nextInt(120);
}
+
+ public static class Builder {
+ private Context mContext;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public ElectricFanLoadingRenderer build() {
+ ElectricFanLoadingRenderer loadingRenderer = new ElectricFanLoadingRenderer(mContext);
+ return loadingRenderer;
+ }
+ }
}
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/shapechange/CircleBroodLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/shapechange/CircleBroodLoadingRenderer.java
index d8dbbf4..8fb83f1 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/shapechange/CircleBroodLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/shapechange/CircleBroodLoadingRenderer.java
@@ -108,7 +108,7 @@ public class CircleBroodLoadingRenderer extends LoadingRenderer {
private float mStageChildForwardBottomLeftLength;
private float mStageChildBackwardBottomLeftLength;
- public CircleBroodLoadingRenderer(Context context) {
+ private CircleBroodLoadingRenderer(Context context) {
super(context);
init(context);
setupPaint();
@@ -131,7 +131,7 @@ private void init(Context context) {
mMaxRevealCircleRadius = (int) (Math.sqrt(mWidth * mWidth + mHeight * mHeight) / 2 + 1);
- setDuration(ANIMATION_DURATION);
+ mDuration = ANIMATION_DURATION;
}
private void setupPaint() {
@@ -141,7 +141,7 @@ private void setupPaint() {
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas, Rect bounds) {
int saveCount = canvas.save();
RectF arcBounds = mCurrentBounds;
@@ -258,7 +258,7 @@ private Path createLinkPath() {
}
@Override
- public void computeRender(float renderProgress) {
+ protected void computeRender(float renderProgress) {
if (mCurrentBounds.isEmpty()) {
return;
}
@@ -598,19 +598,19 @@ private float getRestLength(Path path, float startD) {
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
+
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
+
}
@Override
- public void reset() {
+ protected void reset() {
}
private class MotherMoveInterpolator implements Interpolator {
@@ -661,4 +661,17 @@ public float getInterpolation(float input) {
return result;
}
}
+
+ public static class Builder {
+ private Context mContext;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+
+ public CircleBroodLoadingRenderer build() {
+ CircleBroodLoadingRenderer loadingRenderer = new CircleBroodLoadingRenderer(mContext);
+ return loadingRenderer;
+ }
+ }
}
\ No newline at end of file
diff --git a/library/src/main/java/app/dinus/com/loadingdrawable/render/shapechange/CoolWaitLoadingRenderer.java b/library/src/main/java/app/dinus/com/loadingdrawable/render/shapechange/CoolWaitLoadingRenderer.java
index 85dc7ed..a404e78 100644
--- a/library/src/main/java/app/dinus/com/loadingdrawable/render/shapechange/CoolWaitLoadingRenderer.java
+++ b/library/src/main/java/app/dinus/com/loadingdrawable/render/shapechange/CoolWaitLoadingRenderer.java
@@ -60,7 +60,7 @@ public class CoolWaitLoadingRenderer extends LoadingRenderer {
private int mMiddleColor;
private int mBottomColor;
- public CoolWaitLoadingRenderer(Context context) {
+ private CoolWaitLoadingRenderer(Context context) {
super(context);
init(context);
setupPaint();
@@ -76,7 +76,7 @@ private void init(Context context) {
mMiddleColor = Color.parseColor("#FFF3C742");
mBottomColor = Color.parseColor("#FF89CC59");
- setDuration(ANIMATION_DURATION);
+ mDuration = ANIMATION_DURATION;
}
private void setupPaint() {
@@ -88,7 +88,7 @@ private void setupPaint() {
}
@Override
- public void draw(Canvas canvas, Rect bounds) {
+ protected void draw(Canvas canvas, Rect bounds) {
int saveCount = canvas.save();
RectF arcBounds = mCurrentBounds;
arcBounds.set(bounds);
@@ -145,7 +145,7 @@ private Path createWaitPath(RectF bounds) {
}
@Override
- public void computeRender(float renderProgress) {
+ protected void computeRender(float renderProgress) {
if (mCurrentBounds.isEmpty()) {
return;
}
@@ -240,20 +240,31 @@ public void computeRender(float renderProgress) {
}
@Override
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
- invalidateSelf();
+
}
@Override
- public void setColorFilter(ColorFilter cf) {
+ protected void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
- invalidateSelf();
+
}
@Override
- public void reset() {
+ protected void reset() {
}
+ public static class Builder {
+ private Context mContext;
+
+ public Builder(Context mContext) {
+ this.mContext = mContext;
+ }
+ public CoolWaitLoadingRenderer build() {
+ CoolWaitLoadingRenderer loadingRenderer = new CoolWaitLoadingRenderer(mContext);
+ return loadingRenderer;
+ }
+ }
}