Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 32e33a8

Browse files
author
dinuscxj
committed
add SwapLoadingDrawable
1 parent f47cd02 commit 32e33a8

File tree

7 files changed

+183
-16
lines changed

7 files changed

+183
-16
lines changed
-1.45 MB
Binary file not shown.
1.35 MB
Loading

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
some android loading drawable, can be combined with any View as the loading View,
44
and is especially suitable for the loading animation of the [RecyclerRefreshLayout](https://github.com/dinuscxj/RecyclerRefreshLayout).
55

6-
![](https://raw.githubusercontent.com/dinuscxj/LoadingDrawable/master/Preview/CircleLoadingDrawable_Commit2.gif?width=300)
6+
![](https://raw.githubusercontent.com/dinuscxj/LoadingDrawable/master/Preview/CircleLoadingDrawable_Commit3.gif?width=300)
77
## Features
88
* GearLoadingDrawable
99
* WhorlLoadingDrawable
@@ -21,6 +21,7 @@
2121

2222
Used with ImageView
2323
```java
24+
ImageView.setImageDrawable(new LoadingDrawable(new SwapLoadingRenderer(Context)));
2425
ImageView.setImageDrawable(new LoadingDrawable(new GearLoadingRenderer(Context)));
2526
ImageView.setImageDrawable(new LoadingDrawable(new WhorlLoadingRenderer(Context)));
2627
ImageView.setImageDrawable(new LoadingDrawable(new LevelLoadingRenderer(Context)));
@@ -30,6 +31,7 @@
3031

3132
Used with View
3233
```java
34+
View.setBackground(new LoadingDrawable(new SwapLoadingRenderer(Context)));
3335
View.setBackground(new LoadingDrawable(new GearLoadingRenderer(Context)));
3436
View.setBackground(new LoadingDrawable(new WhorlLoadingRenderer(Context)));
3537
View.setBackground(new LoadingDrawable(new LevelLoadingRenderer(Context)));

app/src/main/java/app/dinus/com/example/MainActivity.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,19 @@
99
import app.dinus.com.loadingdrawable.LevelLoadingRenderer;
1010
import app.dinus.com.loadingdrawable.LoadingDrawable;
1111
import app.dinus.com.loadingdrawable.MaterialLoadingRenderer;
12+
import app.dinus.com.loadingdrawable.SwapLoadingRenderer;
1213
import app.dinus.com.loadingdrawable.WhorlLoadingRenderer;
1314

1415

1516
public class MainActivity extends AppCompatActivity {
17+
private LoadingDrawable mSwapDrawable;
1618
private LoadingDrawable mGearDrawable;
1719
private LoadingDrawable mWhorlDrawable;
1820
private LoadingDrawable mLevelDrawable;
1921
private LoadingDrawable mMaterialDrawable;
2022
private LoadingDrawable mCollisionDrawable;
2123

24+
private ImageView mIvSwap;
2225
private ImageView mIvGear;
2326
private ImageView mIvWhorl;
2427
private ImageView mIvLevel;
@@ -30,18 +33,21 @@ protected void onCreate(Bundle savedInstanceState) {
3033
super.onCreate(savedInstanceState);
3134
setContentView(R.layout.activity_main);
3235

36+
mIvSwap = (ImageView) findViewById(R.id.swap_view);
3337
mIvGear = (ImageView) findViewById(R.id.gear_view);
3438
mIvWhorl = (ImageView) findViewById(R.id.whorl_view);
3539
mIvLevel = (ImageView) findViewById(R.id.level_view);
3640
mIvMaterial = (ImageView) findViewById(R.id.material_view);
3741
mIvCollision = (ImageView) findViewById(R.id.collision_view);
3842

43+
mSwapDrawable = new LoadingDrawable(new SwapLoadingRenderer(this));
3944
mGearDrawable = new LoadingDrawable(new GearLoadingRenderer(this));
4045
mWhorlDrawable = new LoadingDrawable(new WhorlLoadingRenderer(this));
4146
mLevelDrawable = new LoadingDrawable(new LevelLoadingRenderer(this));
4247
mMaterialDrawable = new LoadingDrawable(new MaterialLoadingRenderer(this));
4348
mCollisionDrawable = new LoadingDrawable(new CollisionLoadingRenderer(this));
4449

50+
mIvSwap.setImageDrawable(mSwapDrawable);
4551
mIvGear.setImageDrawable(mGearDrawable);
4652
mIvWhorl.setImageDrawable(mWhorlDrawable);
4753
mIvLevel.setImageDrawable(mLevelDrawable);
@@ -52,6 +58,7 @@ protected void onCreate(Bundle savedInstanceState) {
5258
@Override
5359
protected void onStart() {
5460
super.onStart();
61+
mSwapDrawable.start();
5562
mGearDrawable.start();
5663
mWhorlDrawable.start();
5764
mLevelDrawable.start();
@@ -61,6 +68,7 @@ protected void onStart() {
6168

6269
@Override
6370
protected void onStop() {
71+
mSwapDrawable.stop();
6472
mGearDrawable.stop();
6573
mWhorlDrawable.stop();
6674
mLevelDrawable.stop();

app/src/main/res/layout/activity_main.xml

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,11 @@
5959
android:background="#ffe9e4d1"
6060
android:layout_height="match_parent" />
6161

62-
<TextView
63-
android:id="@+id/rotate_view"
62+
<ImageView
63+
android:id="@+id/swap_view"
6464
android:layout_weight="1"
65-
android:gravity="center"
65+
android:layout_height="match_parent"
6666
android:layout_width="0dp"
67-
android:textColor="#ffa10008"
68-
android:textSize="20sp"
69-
android:text="waiting ..."
70-
android:layout_height="match_parent" />
67+
android:background="#ff94d0c1"/>
7168
</LinearLayout>
7269
</LinearLayout>

library/src/main/java/app/dinus/com/loadingdrawable/CollisionLoadingRenderer.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,18 @@ public class CollisionLoadingRenderer extends LoadingRenderer {
2020
private static final Interpolator ACCELERATE_INTERPOLATOR = new AccelerateInterpolator();
2121
private static final Interpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator();
2222

23-
private static final float DEFAULT_WIDTH = 15.0f * 11;
24-
private static final float DEFAULT_HEIGHT = 15.0f * 5;
23+
private static final int CIRCLE_COUNT = 7;
24+
25+
//the 2 * 2 is the left and right side offset
26+
private static final float DEFAULT_WIDTH = 15.0f * (CIRCLE_COUNT + 2 * 2);
27+
//the 2 * 2 is the top and bottom side offset
28+
private static final float DEFAULT_HEIGHT = 15.0f * (1 + 2 * 2);
2529

2630
private static final float DURATION_OFFSET = 0.25f;
2731
private static final float START_LEFT_DURATION_OFFSET = 0.25f;
2832
private static final float START_RIGHT_DURATION_OFFSET = 0.5f;
2933
private static final float END_RIGHT_DURATION_OFFSET = 0.75f;
3034

31-
private static final int CIRCLE_COUNT = 7;
32-
3335
private static final int[] DEFAULT_COLORS = new int[] {
3436
Color.RED, Color.GREEN
3537
};
@@ -72,16 +74,16 @@ public void draw(Canvas canvas, Rect bounds) {
7274
RectF arcBounds = mTempBounds;
7375
arcBounds.set(bounds);
7476

75-
LinearGradient gradient = new LinearGradient(arcBounds.left, 0, arcBounds.right, 0,
76-
mColors, mPositions, Shader.TileMode.CLAMP);
77-
mPaint.setShader(gradient);
78-
7977
float cy = mHeight / 2 ;
8078
float circleRadius = computeCircleRadius(arcBounds);
8179

8280
float sideOffset = 2.0f * (2 * circleRadius);
8381
float maxMoveOffset = 1.5f * (2 * circleRadius);
8482

83+
LinearGradient gradient = new LinearGradient(arcBounds.left + sideOffset, 0, arcBounds.right - sideOffset, 0,
84+
mColors, mPositions, Shader.TileMode.CLAMP);
85+
mPaint.setShader(gradient);
86+
8587
for (int i = 0; i < CIRCLE_COUNT; i++) {
8688
if (i == 0 && mStartXOffsetProgress != 0) {
8789
float xMoveOffset = maxMoveOffset * mStartXOffsetProgress;
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package app.dinus.com.loadingdrawable;
2+
3+
import android.content.Context;
4+
import android.graphics.Canvas;
5+
import android.graphics.Color;
6+
import android.graphics.ColorFilter;
7+
import android.graphics.Paint;
8+
import android.graphics.Rect;
9+
import android.graphics.RectF;
10+
import android.support.v4.view.animation.FastOutSlowInInterpolator;
11+
import android.util.DisplayMetrics;
12+
import android.util.Log;
13+
import android.util.TypedValue;
14+
import android.view.animation.AccelerateInterpolator;
15+
import android.view.animation.DecelerateInterpolator;
16+
import android.view.animation.Interpolator;
17+
18+
public class SwapLoadingRenderer extends LoadingRenderer {
19+
private static final Interpolator MATERIAL_INTERPOLATOR = new FastOutSlowInInterpolator();
20+
21+
private static final int CIRCLE_COUNT = 5;
22+
23+
//(CIRCLE_COUNT - 1) / 2 is the Circle interval width; the 2 * 2 is the both side inset
24+
private static final float DEFAULT_WIDTH = 15.0f * (CIRCLE_COUNT + (CIRCLE_COUNT - 1) / 2 + 2 * 2);
25+
//the 2 * 2 is the both side inset
26+
private static final float DEFAULT_HEIGHT = 15.0f * (1 + 2 * 2);
27+
private static final float DEFAULT_STROKE_WIDTH = 1.5f;
28+
29+
private static final int DEFAULT_COLOR = Color.RED;
30+
31+
private final Paint mPaint = new Paint();
32+
private final RectF mTempBounds = new RectF();
33+
34+
private int mColor;
35+
36+
private int mSwapIndex;
37+
38+
private float mSwapThreshold;
39+
private float mSwapXOffsetProgress;
40+
41+
public SwapLoadingRenderer(Context context) {
42+
super(context);
43+
44+
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
45+
mWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_WIDTH, displayMetrics);
46+
mHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_HEIGHT, displayMetrics);
47+
mStrokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_STROKE_WIDTH, displayMetrics);
48+
49+
mSwapThreshold = 1.0f / CIRCLE_COUNT;
50+
setupPaint();
51+
}
52+
53+
private void setupPaint() {
54+
mColor = DEFAULT_COLOR;
55+
56+
mPaint.setAntiAlias(true);
57+
mPaint.setStrokeWidth(getStrokeWidth());
58+
mPaint.setStyle(Paint.Style.FILL);
59+
}
60+
61+
@Override
62+
public void draw(Canvas canvas, Rect bounds) {
63+
mPaint.setColor(mColor);
64+
65+
int saveCount = canvas.save();
66+
67+
RectF arcBounds = mTempBounds;
68+
arcBounds.set(bounds);
69+
70+
float cy = mHeight / 2 ;
71+
float circleRadius = computeCircleRadius(arcBounds);
72+
73+
float sideOffset = 2.0f * (2 * circleRadius);
74+
float intervalWidth = circleRadius;
75+
76+
float circleDiameter = mSwapIndex == CIRCLE_COUNT - 1
77+
? circleRadius * 2 * (CIRCLE_COUNT + 1)
78+
: circleRadius * 3;
79+
80+
//x^2 + y^2 = (3 * circleRadius / 2) ^ 2
81+
float xMoveOffset = mSwapIndex == CIRCLE_COUNT - 1
82+
? -mSwapXOffsetProgress * circleDiameter
83+
: mSwapXOffsetProgress * circleDiameter;
84+
//the y axial symmetry
85+
float xCoordinate = mSwapIndex == CIRCLE_COUNT - 1
86+
? xMoveOffset + circleDiameter / 2
87+
: xMoveOffset - circleDiameter / 2;
88+
float yMoveOffset = (float) (mSwapIndex % 2 == 0 && mSwapIndex != CIRCLE_COUNT -1
89+
? Math.sqrt(Math.pow(circleDiameter / 2, 2.0f) - Math.pow(xCoordinate, 2.0f))
90+
: -Math.sqrt(Math.pow(circleDiameter / 2, 2.0f) - Math.pow(xCoordinate, 2.0f)));
91+
92+
for (int i = 0; i < CIRCLE_COUNT; i++) {
93+
if (i == mSwapIndex) {
94+
mPaint.setStyle(Paint.Style.FILL);
95+
canvas.drawCircle(circleRadius * (i * 2 + 1) + sideOffset + i * intervalWidth + xMoveOffset
96+
, cy - yMoveOffset, circleRadius - getStrokeWidth() / 2, mPaint);
97+
} else if (i == (mSwapIndex + 1) % CIRCLE_COUNT) {
98+
mPaint.setStyle(Paint.Style.STROKE);
99+
100+
canvas.drawCircle(circleRadius * (i * 2 + 1) + sideOffset + i * intervalWidth - xMoveOffset
101+
, cy + yMoveOffset, circleRadius - getStrokeWidth() / 2, mPaint);
102+
} else {
103+
mPaint.setStyle(Paint.Style.STROKE);
104+
105+
canvas.drawCircle(circleRadius * (i * 2 + 1) + sideOffset + i * intervalWidth, cy,
106+
circleRadius - getStrokeWidth() / 2, mPaint);
107+
}
108+
109+
}
110+
111+
canvas.restoreToCount(saveCount);
112+
}
113+
114+
private float computeCircleRadius(RectF rectBounds) {
115+
float width = rectBounds.width();
116+
float height = rectBounds.height();
117+
118+
//CIRCLE_COUNT + 4 is the sliding distance of both sides
119+
float radius = Math.min(width / (CIRCLE_COUNT + (CIRCLE_COUNT - 1) / 2 + 2 * 2) / 2, height / 2);
120+
return radius;
121+
}
122+
123+
@Override
124+
public void computeRender(float renderProgress) {
125+
mSwapIndex = (int) (renderProgress / mSwapThreshold);
126+
mSwapXOffsetProgress = MATERIAL_INTERPOLATOR.getInterpolation(
127+
(renderProgress - mSwapIndex * mSwapThreshold) / mSwapThreshold);
128+
129+
invalidateSelf();
130+
}
131+
132+
@Override
133+
public void setAlpha(int alpha) {
134+
mPaint.setAlpha(alpha);
135+
invalidateSelf();
136+
}
137+
138+
@Override
139+
public void setColorFilter(ColorFilter cf) {
140+
mPaint.setColorFilter(cf);
141+
invalidateSelf();
142+
}
143+
144+
@Override
145+
public void reset() {
146+
}
147+
148+
public void setColor(int color) {
149+
mColor = color;
150+
}
151+
152+
@Override
153+
public void setStrokeWidth(float strokeWidth) {
154+
super.setStrokeWidth(strokeWidth);
155+
mPaint.setStrokeWidth(strokeWidth);
156+
invalidateSelf();
157+
}
158+
}

0 commit comments

Comments
 (0)