├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── github
│ │ └── glomadrian
│ │ └── loadingballssample
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── github
│ │ │ └── glomadrian
│ │ │ └── loadingballssample
│ │ │ └── MainActivity.java
│ └── res
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── arrays.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── github
│ └── glomadrian
│ └── loadingballssample
│ └── ExampleUnitTest.java
├── art
├── 1.gif
├── 10.gif
├── 11.gif
├── 12.gif
├── 13.gif
├── 14.gif
├── 15.gif
├── 2.gif
├── 3.gif
├── 4.gif
├── 5.gif
├── 6.gif
├── 7.gif
├── 8.gif
├── 9.gif
└── smallAndroidArsenal.gif
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── loadingballs
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── github
│ │ └── glomadrian
│ │ └── loadingballs
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── github
│ │ │ └── glomadrian
│ │ │ └── loadingballs
│ │ │ ├── Ball.java
│ │ │ ├── BallView.java
│ │ │ ├── animator
│ │ │ ├── AbstractBallAnimator.java
│ │ │ ├── BallPathAnimator.java
│ │ │ └── BallSizeAnimator.java
│ │ │ └── factory
│ │ │ ├── PathFactory.java
│ │ │ └── path
│ │ │ ├── BallPath.java
│ │ │ ├── Circle.java
│ │ │ ├── Diamond.java
│ │ │ ├── Infinite.java
│ │ │ ├── Square.java
│ │ │ ├── Star.java
│ │ │ └── Triangle.java
│ └── res
│ │ └── values
│ │ ├── atrrs.xml
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── github
│ └── glomadrian
│ └── loadingballs
│ └── ExampleUnitTest.java
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.gitignore.io
2 |
3 | ### Gradle ###
4 | .gradle
5 | build/
6 |
7 | # Ignore Gradle GUI config
8 | gradle-app.setting
9 |
10 |
11 | ### Android ###
12 | # Built application files
13 | *.apk
14 | *.ap_
15 |
16 | # Files for the Dalvik VM
17 | *.dex
18 |
19 | # Java class files
20 | *.class
21 |
22 | # Generated files
23 | bin/
24 | gen/
25 |
26 | # Gradle files
27 | .gradle/
28 | build/
29 |
30 | # Local configuration file (sdk path, etc)
31 | local.properties
32 |
33 | # Proguard folder generated by Eclipse
34 | proguard/
35 |
36 | # Log Fhttp://www.ikea.com/es/es/catalog/availability/00198039/iles
37 | *.log
38 |
39 |
40 | ### Intellij ###
41 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
42 |
43 | *.iml
44 |
45 | ## Directory-based project format:
46 | .idea/
47 | # if you remove the above rule, at least ignore the following:
48 |
49 | # User-specific stuff:
50 | # .idea/workspace.xml
51 | # .idea/tasks.xml
52 | # .idea/dictionaries
53 |
54 | # Sensitive or high-churn files:
55 | # .idea/dataSources.ids
56 | # .idea/dataSources.xml
57 | # .idea/sqlDataSources.xml
58 | # .idea/dynamic.xml
59 | # .idea/uiDesigner.xml
60 |
61 | # Gradle:
62 | # .idea/gradle.xml
63 | # .idea/libraries
64 |
65 | # Mongo Explorer plugin:
66 | # .idea/mongoSettings.xml
67 |
68 | ## File-based project format:
69 | *.ipr
70 | *.iws
71 |
72 | ## Plugin-specific files:
73 |
74 | # IntelliJ
75 | out/
76 |
77 | # mpeltonen/sbt-idea plugin
78 | .idea_modules/
79 |
80 | # JIRA plugin
81 | atlassian-ide-plugin.xml
82 |
83 | # Crashlytics plugin (for Android Studio and IntelliJ)
84 | com_crashlytics_export_strings.xml
85 | crashlytics.properties
86 | crashlytics-build.properties
87 |
88 |
89 | ### Java ###
90 | *.class
91 |
92 | # Mobile Tools for Java (J2ME)
93 | .mtj.tmp/
94 |
95 | # Package Files #
96 | *.jar
97 | *.war
98 | *.ear
99 |
100 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
101 | hs_err_pid*
102 | *.hprof
103 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Loading Balls
2 | -----------------
3 | [ ](https://bintray.com/glomadrian/maven/loading-balls/_latestVersion)
4 |
5 |
6 | A highly configurable library to do loading progress with animated balls for
7 | Android
8 |
9 |
10 |
11 | ![Demo Screenshot][1]
12 |
13 |
14 | How to use
15 | ----------
16 |
17 | ### Custom attributes
18 |
19 |
20 | ``` xml
21 | lib:path="triangle"
22 | ```
23 | The shape of the movement, available:
24 |
25 | * infinite
26 | * square
27 | * triangle
28 | * circle
29 | * diamond
30 | * star
31 |
32 |
33 | ``` xml
34 | lib:balls="3"
35 | ```
36 | Number of balls used in the animation
37 |
38 | ``` xml
39 | lib:movement_cycle_time="1500"
40 | ```
41 | The time which the ball takes to do a complete cicle
42 |
43 | ``` xml
44 | lib:enable_size_animation="true"
45 | ```
46 | Enables the size animation in the balls (by default is false)
47 |
48 | ``` xml
49 | lib:size_cycle_time="500"
50 | ```
51 | The time it takes to the ball to grow up and decrease the size one time
52 |
53 |
54 | ``` xml
55 | lib:ball_size="6dp"
56 | ```
57 | Set the balls size
58 |
59 | ``` xml
60 | lib:min_ball_size="5dp"
61 | lib:max_ball_size="12dp"
62 | ```
63 | To use with enable_size_animation="true", set the min and the max ball size
64 |
65 | ``` xml
66 | lib:ball_colors="@array/colors"
67 | ```
68 | Array of colors for the balls, if there are more balls than colors then repeat
69 | color balls
70 |
71 | ``` xml
72 |
73 |
74 | #FFD91C
75 | #FF4B4A
76 | #3D8EFF
77 |
78 |
79 | - @color/ball1
80 | - @color/ball2
81 | - @color/ball3
82 |
83 |
84 | ```
85 | Sample colors array
86 |
87 | For Gradle
88 | ---------------------
89 |
90 | Add repository
91 |
92 | ```java
93 | repositories {
94 | maven {
95 | url "http://dl.bintray.com/glomadrian/maven"
96 | }
97 | }
98 | ```
99 | Add dependency
100 | ```java
101 | compile 'com.github.glomadrian:loadingballs:1.1@aar'
102 | ```
103 |
104 |
105 | ### Some Samples
106 |
107 | #### Default Infinite shape
108 |
109 | ![Sample][1]
110 |
111 |
112 | ``` xml
113 |
126 | ```
127 |
128 | #### Infinite shape without size animation
129 |
130 | ![Sample][2]
131 |
132 | ``` xml
133 |
143 | ```
144 | #### Infinite shape with 5 balls
145 |
146 | ![Sample][3]
147 |
148 | ``` xml
149 |
162 | ```
163 |
164 | #### Triangle shape with 3 balls and size animation
165 |
166 | ![Sample][4]
167 |
168 | ``` xml
169 |
183 | ```
184 |
185 | #### Triangle shape with 2 balls
186 |
187 | ![Sample][5]
188 |
189 | ``` xml
190 |
201 | ```
202 |
203 | #### Square shape with 3 balls
204 |
205 | ![Sample][6]
206 |
207 | ``` xml
208 |
219 | ```
220 |
221 | #### Square shape with 5 balls and size animation
222 |
223 | ![Sample][7]
224 |
225 | ``` xml
226 |
240 | ```
241 |
242 | #### Circle shape with 3 balls and size animation
243 |
244 | ![Sample][8]
245 |
246 | ``` xml
247 |
261 | ```
262 | #### Circle shape with 2 balls without size animation
263 |
264 | ![Sample][9]
265 |
266 | ``` xml
267 |
278 | ```
279 | #### Star shape with 10 balls without size animation
280 |
281 | ![Sample][10]
282 |
283 | ``` xml
284 |
296 | ```
297 | #### Star shape with 5 balls and size animation
298 |
299 | ![Sample][11]
300 | ``` xml
301 |
316 | ```
317 | #### Star shape with 3 balls and size animation
318 |
319 | ![Sample][12]
320 |
321 | ``` xml
322 |
337 | ```
338 | #### Diamond shape with 5 balls without size animation
339 |
340 | ![Sample][14]
341 |
342 | ``` xml
343 |
354 | ```
355 | #### Diamond shape with 4 balls and size animation
356 |
357 | ![Sample][13]
358 |
359 | ``` xml
360 |
375 | ```
376 | #### Diamond shape with 10 balls without size animation
377 |
378 | ![Sample][15]
379 |
380 |
381 | ``` xml
382 |
393 | ```
394 |
395 | Developed By
396 | ------------
397 | Adrián García Lomas -
398 | * [Twitter](https://twitter.com/glomadrian)
399 | * [LinkedIn](https://es.linkedin.com/in/glomadrian )
400 |
401 | License
402 | -------
403 |
404 | Copyright 2015 Adrián García Lomas
405 |
406 | Licensed under the Apache License, Version 2.0 (the "License");
407 | you may not use this file except in compliance with the License.
408 | You may obtain a copy of the License at
409 |
410 | http://www.apache.org/licenses/LICENSE-2.0
411 |
412 | Unless required by applicable law or agreed to in writing, software
413 | distributed under the License is distributed on an "AS IS" BASIS,
414 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
415 | See the License for the specific language governing permissions and
416 | limitations under the License.
417 |
418 | [1]: ./art/1.gif
419 | [2]: ./art/2.gif
420 | [3]: ./art/3.gif
421 | [4]: ./art/4.gif
422 | [5]: ./art/5.gif
423 | [6]: ./art/6.gif
424 | [7]: ./art/7.gif
425 | [8]: ./art/8.gif
426 | [9]: ./art/9.gif
427 | [10]: ./art/10.gif
428 | [11]: ./art/11.gif
429 | [12]: ./art/12.gif
430 | [13]: ./art/13.gif
431 | [14]: ./art/14.gif
432 | [15]: ./art/15.gif
433 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.1"
6 |
7 | defaultConfig {
8 | applicationId "com.github.glomadrian.loadingballssample"
9 | minSdkVersion 16
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | compile project(':loadingballs')
25 | testCompile 'junit:junit:4.12'
26 | compile 'com.android.support:appcompat-v7:23.1.1'
27 | }
28 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /media/Almacen/SDK/Android/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/github/glomadrian/loadingballssample/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/github/glomadrian/loadingballssample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballssample;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 |
6 | public class MainActivity extends AppCompatActivity {
7 |
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | setContentView(R.layout.activity_main);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
18 |
19 |
32 |
33 |
43 |
44 |
57 |
58 |
68 |
69 |
83 |
84 |
95 |
96 |
107 |
108 |
122 |
123 |
137 |
138 |
152 |
153 |
164 |
165 |
177 |
178 |
193 |
194 |
209 |
210 |
225 |
226 |
237 |
238 |
249 |
250 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFD91C
4 | #FF4B4A
5 | #3D8EFF
6 |
7 |
8 | - @color/ball1
9 | - @color/ball2
10 | - @color/ball3
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | LoadingBalls
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/github/glomadrian/loadingballssample/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/art/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/1.gif
--------------------------------------------------------------------------------
/art/10.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/10.gif
--------------------------------------------------------------------------------
/art/11.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/11.gif
--------------------------------------------------------------------------------
/art/12.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/12.gif
--------------------------------------------------------------------------------
/art/13.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/13.gif
--------------------------------------------------------------------------------
/art/14.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/14.gif
--------------------------------------------------------------------------------
/art/15.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/15.gif
--------------------------------------------------------------------------------
/art/2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/2.gif
--------------------------------------------------------------------------------
/art/3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/3.gif
--------------------------------------------------------------------------------
/art/4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/4.gif
--------------------------------------------------------------------------------
/art/5.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/5.gif
--------------------------------------------------------------------------------
/art/6.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/6.gif
--------------------------------------------------------------------------------
/art/7.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/7.gif
--------------------------------------------------------------------------------
/art/8.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/8.gif
--------------------------------------------------------------------------------
/art/9.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/9.gif
--------------------------------------------------------------------------------
/art/smallAndroidArsenal.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glomadrian/loading-balls/a3c3d792d570ca58ac36fb85b4c6cbc26b8cad9d/art/smallAndroidArsenal.gif
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.5.0'
9 | classpath 'com.github.dcendents:android-maven-plugin:1.2'
10 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.1'
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | jcenter()
19 | }
20 | }
21 |
22 | task clean(type: Delete) {
23 | delete rootProject.buildDir
24 | }
25 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Oct 21 11:34:03 PDT 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/loadingballs/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/loadingballs/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.1"
6 |
7 | defaultConfig {
8 | minSdkVersion 16
9 | targetSdkVersion 23
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile fileTree(dir: 'libs', include: ['*.jar'])
23 | testCompile 'junit:junit:4.12'
24 | compile 'com.android.support:appcompat-v7:23.1.1'
25 | }
26 |
--------------------------------------------------------------------------------
/loadingballs/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /media/Almacen/SDK/Android/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/loadingballs/src/androidTest/java/com/github/glomadrian/loadingballs/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/loadingballs/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/Ball.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.Point;
6 |
7 | /**
8 | * @author Adrián García Lomas
9 | */
10 | public class Ball {
11 |
12 | private Paint paint;
13 | private float size;
14 | private Point position;
15 | private int color;
16 |
17 | public Ball(int size) {
18 | this.size = size;
19 | init();
20 | }
21 |
22 | public Ball(float size, int color) {
23 | this.color = color;
24 | this.size = size;
25 | init();
26 | }
27 |
28 | private void init() {
29 | initPaint();
30 | initPoint();
31 | }
32 |
33 | private void initPaint() {
34 | paint = new Paint();
35 | paint.setColor(color);
36 | paint.setAntiAlias(true);
37 | }
38 |
39 | private void initPoint() {
40 | position = new Point();
41 | }
42 |
43 | public Paint getPaint() {
44 | return paint;
45 | }
46 |
47 | public void setPaint(Paint paint) {
48 | this.paint = paint;
49 | }
50 |
51 | public int getColor() {
52 | return color;
53 | }
54 |
55 | public void setColor(int color) {
56 | this.color = color;
57 | }
58 |
59 | public float getSize() {
60 | return size;
61 | }
62 |
63 | public void setSize(float size) {
64 | this.size = size;
65 | }
66 |
67 | public Point getPosition() {
68 | return position;
69 | }
70 |
71 | public void setPosition(int x, int y) {
72 | this.position.set(x, y);
73 | }
74 |
75 | public void render(Canvas canvas) {
76 | canvas.drawCircle(position.x, position.y, size, paint);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/BallView.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Path;
7 | import android.graphics.Point;
8 | import android.util.AttributeSet;
9 | import android.view.View;
10 | import com.github.glomadrian.loadingballs.animator.AbstractBallAnimator;
11 | import com.github.glomadrian.loadingballs.animator.BallPathAnimator;
12 | import com.github.glomadrian.loadingballs.animator.BallSizeAnimator;
13 | import com.github.glomadrian.loadingballs.factory.PathFactory;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | /**
18 | * @author Adrián García Lomas
19 | */
20 | public class BallView extends View {
21 |
22 | private List balls;
23 | private float minBallSize;
24 | private float maxBallSize;
25 | private float ballSize = 20;
26 | private BallPathAnimator ballPathAnimator;
27 | private BallSizeAnimator ballSizeAnimator;
28 | private int numberOfBalls = 3;
29 | private int ballSizeAnimationDuration = 400;
30 | private int ballPathAnimationDuration = 1500;
31 | private boolean sizeAnimationEnabled = false;
32 | private int[] ballColors;
33 | private String pathType;
34 |
35 | public BallView(Context context, AttributeSet attrs) {
36 | super(context, attrs);
37 | init(attrs);
38 | }
39 |
40 | public BallView(Context context, AttributeSet attrs, int defStyleAttr) {
41 | super(context, attrs, defStyleAttr);
42 | init(attrs);
43 | }
44 |
45 | private void init(AttributeSet attrs) {
46 | defaultBallColors();
47 | initAttributes(attrs);
48 | createBalls();
49 | }
50 |
51 | private void defaultBallColors() {
52 | ballColors = new int[] { -9956, -46262, -12742913 };
53 | }
54 |
55 | private void initAttributes(AttributeSet attrs) {
56 | TypedArray attributes = getContext().obtainStyledAttributes(attrs, R.styleable.LoadingBalls);
57 | numberOfBalls = attributes.getInt(R.styleable.LoadingBalls_balls, numberOfBalls);
58 | ballSize = attributes.getDimension(R.styleable.LoadingBalls_ball_size, ballSize);
59 | minBallSize = attributes.getDimension(R.styleable.LoadingBalls_min_ball_size, ballSize / 2);
60 | maxBallSize = attributes.getDimension(R.styleable.LoadingBalls_max_ball_size, ballSize * 2);
61 | ballSizeAnimationDuration =
62 | attributes.getInt(R.styleable.LoadingBalls_size_cycle_time, ballSizeAnimationDuration);
63 | ballPathAnimationDuration =
64 | attributes.getInt(R.styleable.LoadingBalls_movement_cycle_time, ballPathAnimationDuration);
65 | sizeAnimationEnabled =
66 | attributes.getBoolean(R.styleable.LoadingBalls_enable_size_animation, false);
67 | initColorsAttributes(attributes);
68 | pathType = attributes.getString(R.styleable.LoadingBalls_path);
69 | if (pathType == null) {
70 | pathType = PathFactory.INFINITE;
71 | }
72 | }
73 |
74 | private void initColorsAttributes(TypedArray attributes) {
75 | int arrayResourceId = attributes.getResourceId(R.styleable.LoadingBalls_ball_colors, 0);
76 | if (arrayResourceId != 0) {
77 | ballColors = getResources().getIntArray(arrayResourceId);
78 | }
79 | }
80 |
81 | @Override
82 | protected void onSizeChanged(int w, int h, int oldw, int oldh) {
83 | super.onSizeChanged(w, h, oldw, oldh);
84 | Path path = PathFactory.makePath(pathType, new Point(w / 2, h / 2), w, h, (int) maxBallSize);
85 | initBallPathAnimator(path);
86 | if (sizeAnimationEnabled) {
87 | initBallSizeAnimator(path);
88 | }
89 | start();
90 | }
91 |
92 | private void initBallPathAnimator(Path path) {
93 | ballPathAnimator = new BallPathAnimator(path, ballPathAnimationDuration);
94 | ballPathAnimator.setBallPathAnimatorListener(new AnimatorListener());
95 | ballPathAnimator.addBalls(balls);
96 | }
97 |
98 | private void initBallSizeAnimator(Path path) {
99 | ballSizeAnimator =
100 | new BallSizeAnimator(path, ballSizeAnimationDuration, minBallSize, maxBallSize);
101 | ballSizeAnimator.addBalls(balls);
102 | }
103 |
104 | private void createBalls() {
105 | balls = new ArrayList<>();
106 | for (int i = 0, k = 0; i < numberOfBalls; i++, k++) {
107 | if (!(ballColors.length - 1 >= k)) {
108 | k = 0;
109 | }
110 | balls.add(new Ball(ballSize, ballColors[k]));
111 | }
112 | }
113 |
114 | public void start() {
115 | ballPathAnimator.start();
116 | if (sizeAnimationEnabled) {
117 | ballSizeAnimator.start();
118 | }
119 | }
120 |
121 | public void stop() {
122 | ballPathAnimator.stop();
123 | if (sizeAnimationEnabled) {
124 | ballSizeAnimator.start();
125 | }
126 | }
127 |
128 | public void restart() {
129 | ballPathAnimator.restart();
130 | if (sizeAnimationEnabled) {
131 | ballSizeAnimator.restart();
132 | }
133 | }
134 |
135 | @Override
136 | protected void onDraw(Canvas canvas) {
137 | for (Ball ball : balls) {
138 | ball.render(canvas);
139 | }
140 | }
141 |
142 | private class AnimatorListener implements AbstractBallAnimator.BallAnimatorListener {
143 |
144 | @Override
145 | public void onUpdate() {
146 | invalidate();
147 | }
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/animator/AbstractBallAnimator.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs.animator;
2 |
3 | import com.github.glomadrian.loadingballs.Ball;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | /**
8 | * @author Adrián García Lomas
9 | */
10 | public abstract class AbstractBallAnimator {
11 |
12 | protected List balls;
13 | protected BallAnimatorListener ballAnimatorListener;
14 |
15 | public AbstractBallAnimator() {
16 | balls = new ArrayList<>();
17 | }
18 |
19 | public void addBall(Ball ball) {
20 | balls.add(ball);
21 | }
22 |
23 | public void addBalls(List balls) {
24 | this.balls.addAll(balls);
25 | }
26 |
27 | public void setBallPathAnimatorListener(BallAnimatorListener ballAnimatorListener) {
28 | this.ballAnimatorListener = ballAnimatorListener;
29 | }
30 |
31 | public abstract void start();
32 |
33 | public abstract void stop();
34 |
35 | public abstract void restart();
36 |
37 | public interface BallAnimatorListener {
38 |
39 | void onUpdate();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/animator/BallPathAnimator.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs.animator;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.graphics.Path;
5 | import android.graphics.PathMeasure;
6 | import android.view.animation.BaseInterpolator;
7 | import android.view.animation.LinearInterpolator;
8 | import com.github.glomadrian.loadingballs.Ball;
9 |
10 | /**
11 | * Given a Path object trace the points and use value animator
12 | * to go over the points
13 | *
14 | * @author Adrián García Lomas
15 | */
16 | public class BallPathAnimator extends AbstractBallAnimator
17 | implements ValueAnimator.AnimatorUpdateListener {
18 |
19 | private BaseInterpolator interpolator;
20 | private Path path;
21 | private int duration;
22 | private ValueAnimator valueAnimator;
23 | private float offset;
24 |
25 | public BallPathAnimator(BaseInterpolator interpolator, Path path, int duration) {
26 | this.interpolator = interpolator;
27 | this.path = path;
28 | this.duration = duration;
29 | init();
30 | }
31 |
32 | public BallPathAnimator(Path path, int duration) {
33 | this.path = path;
34 | this.duration = duration;
35 | interpolator = new LinearInterpolator();
36 | init();
37 | }
38 |
39 | private void init() {
40 | initValueAnimator();
41 | }
42 |
43 | private void initValueAnimator() {
44 | valueAnimator = new ValueAnimator();
45 | valueAnimator.setRepeatMode(ValueAnimator.INFINITE);
46 | valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
47 | valueAnimator.setDuration(duration);
48 | valueAnimator.setFloatValues(0, 1f);
49 | valueAnimator.setInterpolator(interpolator);
50 | valueAnimator.addUpdateListener(this);
51 | }
52 |
53 | @Override
54 | public void start() {
55 | float size = balls.size();
56 | offset = 1 / size;
57 | valueAnimator.start();
58 | }
59 |
60 | @Override
61 | public void stop(){
62 | valueAnimator.cancel();
63 | }
64 |
65 | @Override
66 | public void restart(){
67 | stop();
68 | start();
69 | }
70 |
71 | @Override
72 | public void onAnimationUpdate(ValueAnimator animation) {
73 | float value = animation.getAnimatedFraction();
74 |
75 | for (int i = 0; i < balls.size(); i++) {
76 | updateBall(balls.get(i), value, i, path);
77 | }
78 |
79 | if (ballAnimatorListener != null) {
80 | ballAnimatorListener.onUpdate();
81 | }
82 | }
83 |
84 | private void updateBall(Ball ball, float fraction, int position, Path path) {
85 | float ballFraction = fraction + (position * offset);
86 | if (ballFraction > 1) {
87 | ballFraction = ballFraction - 1;
88 | }
89 | float[] coordinates = getPathCoordinates(path, ballFraction);
90 | ball.setPosition((int) coordinates[0], (int) coordinates[1]);
91 | }
92 |
93 | private float[] getPathCoordinates(Path path, float fraction) {
94 | float aCoordinates[] = { 0f, 0f };
95 | PathMeasure pm = new PathMeasure(path, false);
96 | pm.getPosTan(pm.getLength() * fraction, aCoordinates, null);
97 | return aCoordinates;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/animator/BallSizeAnimator.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs.animator;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.graphics.Path;
5 | import android.view.animation.AccelerateDecelerateInterpolator;
6 | import com.github.glomadrian.loadingballs.Ball;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | /**
11 | * @author Adrián García Lomas
12 | */
13 | public class BallSizeAnimator extends AbstractBallAnimator {
14 |
15 | private int duration;
16 | private float offset;
17 | private Path path;
18 | private float minBallSize;
19 | private float maxBallSize;
20 | private List animators;
21 |
22 | public BallSizeAnimator(Path path, int duration, float minBallSize, float maxBallSize) {
23 | this.duration = duration;
24 | this.path = path;
25 | this.minBallSize = minBallSize;
26 | this.maxBallSize = maxBallSize;
27 | init();
28 | }
29 |
30 | private void init() {
31 | animators = new ArrayList<>();
32 | }
33 |
34 | public void start() {
35 | animators.clear();
36 | for (int i = 0; i < balls.size(); i++) {
37 | createBallAnimatorAndStart(balls.get(i), 300 * i);
38 | }
39 | }
40 |
41 | @Override
42 | public void stop() {
43 | for (ValueAnimator animator : animators) {
44 | animator.cancel();
45 | }
46 | }
47 |
48 | @Override
49 | public void restart() {
50 | stop();
51 | start();
52 | }
53 |
54 | private void createBallAnimatorAndStart(Ball ball, int startDelay) {
55 | ValueAnimator valueAnimator = new ValueAnimator();
56 | valueAnimator.setFloatValues(minBallSize, maxBallSize);
57 | valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
58 | valueAnimator.setDuration(duration);
59 | valueAnimator.addUpdateListener(new BallUpdateListener(ball));
60 | valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
61 | valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
62 | valueAnimator.setStartDelay(startDelay);
63 | animators.add(valueAnimator);
64 | valueAnimator.start();
65 | }
66 |
67 | private class BallUpdateListener implements ValueAnimator.AnimatorUpdateListener {
68 |
69 | private Ball ball;
70 |
71 | public BallUpdateListener(Ball ball) {
72 | this.ball = ball;
73 | }
74 |
75 | @Override
76 | public void onAnimationUpdate(ValueAnimator animation) {
77 | float value = (float) animation.getAnimatedValue();
78 | ball.setSize((int) value);
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/factory/PathFactory.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs.factory;
2 |
3 | import android.graphics.Path;
4 | import android.graphics.Point;
5 | import com.github.glomadrian.loadingballs.factory.path.Circle;
6 | import com.github.glomadrian.loadingballs.factory.path.Diamond;
7 | import com.github.glomadrian.loadingballs.factory.path.Infinite;
8 | import com.github.glomadrian.loadingballs.factory.path.Square;
9 | import com.github.glomadrian.loadingballs.factory.path.Star;
10 | import com.github.glomadrian.loadingballs.factory.path.Triangle;
11 |
12 | /**
13 | * @author Adrián García Lomas
14 | */
15 | public class PathFactory {
16 |
17 | public static final String CIRCLE = "circle";
18 | public static final String SQUARE = "square";
19 | public static final String INFINITE = "infinite";
20 | public static final String STAR = "star";
21 | public static final String TRIANGLE = "triangle";
22 | public static final String DIAMOND = "diamond";
23 |
24 | public static Path makePath(String path, Point center, int pathWidth, int pathHeight,
25 | int maxBallSize) {
26 |
27 | switch (path) {
28 | case CIRCLE:
29 | return new Circle(center, pathWidth, pathHeight, maxBallSize).draw();
30 | case SQUARE:
31 | return new Square(center, pathWidth, pathHeight, maxBallSize).draw();
32 | case INFINITE:
33 | return new Infinite(center, pathWidth, pathHeight, maxBallSize).draw();
34 | case STAR:
35 | return new Star(center, pathWidth, pathHeight, maxBallSize).draw();
36 | case TRIANGLE:
37 | return new Triangle(center, pathWidth, pathHeight, maxBallSize).draw();
38 | case DIAMOND:
39 | return new Diamond(center, pathWidth, pathHeight, maxBallSize).draw();
40 | default:
41 | return new Infinite(center, pathWidth, pathHeight, maxBallSize).draw();
42 | }
43 | }
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/factory/path/BallPath.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs.factory.path;
2 |
3 | import android.graphics.Path;
4 | import android.graphics.Point;
5 |
6 | /**
7 | * @author Adrián García Lomas
8 | */
9 | public abstract class BallPath {
10 |
11 | protected Point center;
12 | protected int pathWidth;
13 | protected int pathHeight;
14 | protected int maxBallSize;
15 |
16 | public BallPath(Point center, int pathWidth, int pathHeight, int maxBallSize) {
17 | this.center = center;
18 | this.pathWidth = pathWidth;
19 | this.pathHeight = pathHeight;
20 | this.maxBallSize = maxBallSize;
21 | }
22 |
23 | public abstract Path draw();
24 |
25 | protected void initializePoints(Point[] points) {
26 | for (int i = 0; i < points.length; i++) {
27 | points[i] = new Point();
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/factory/path/Circle.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs.factory.path;
2 |
3 | import android.graphics.Path;
4 | import android.graphics.Point;
5 |
6 | /**
7 | * @author Adrián García Lomas
8 | */
9 | public class Circle extends BallPath {
10 |
11 | public Circle(Point center, int pathWidth, int pathHeight, int maxBallSize) {
12 | super(center, pathWidth, pathHeight, maxBallSize);
13 | }
14 |
15 | @Override
16 | public Path draw() {
17 | Path path = new Path();
18 | path.addCircle(center.x, center.y, pathWidth / 2 - maxBallSize, Path.Direction.CCW);
19 | return path;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/factory/path/Diamond.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs.factory.path;
2 |
3 | import android.graphics.Path;
4 | import android.graphics.Point;
5 |
6 | /**
7 | * @author Adrián García Lomas
8 | */
9 | public class Diamond extends BallPath {
10 |
11 | public Diamond(Point center, int pathWidth, int pathHeight, int maxBallSize) {
12 | super(center, pathWidth, pathHeight, maxBallSize);
13 | }
14 |
15 | @Override
16 | public Path draw() {
17 | Point[] diamondPoints = new Point[4];
18 | initializePoints(diamondPoints);
19 |
20 | int diamondWith = pathWidth - maxBallSize * 2;
21 | int middleDiamondWith = diamondWith / 2;
22 |
23 | diamondPoints[0].set(center.x - middleDiamondWith, center.y);
24 | diamondPoints[1].set(center.x, maxBallSize);
25 | diamondPoints[2].set(center.x + middleDiamondWith, center.y);
26 | diamondPoints[3].set(center.x, pathHeight - maxBallSize);
27 |
28 | Path path = new Path();
29 | path.moveTo(diamondPoints[0].x, diamondPoints[0].y);
30 | path.lineTo(diamondPoints[1].x, diamondPoints[1].y);
31 | path.lineTo(diamondPoints[2].x, diamondPoints[2].y);
32 | path.lineTo(diamondPoints[3].x, diamondPoints[3].y);
33 | path.close();
34 |
35 | return path;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/factory/path/Infinite.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs.factory.path;
2 |
3 | import android.graphics.Path;
4 | import android.graphics.Point;
5 |
6 | /**
7 | * @author Adrián García Lomas
8 | */
9 | public class Infinite extends BallPath {
10 |
11 | public Infinite(Point center, int pathWidth, int pathHeight, int maxBallSize) {
12 | super(center, pathWidth, pathHeight, maxBallSize);
13 | }
14 |
15 | @Override
16 | public Path draw() {
17 | pathWidth = pathWidth / 2 - maxBallSize;
18 | Point controlPoint1 = new Point();
19 | controlPoint1.set(center.x - pathWidth / 2, center.y - pathHeight);
20 | Point controlPoint2 = new Point();
21 | controlPoint2.set(center.x + pathWidth / 2, center.y + pathHeight);
22 |
23 | Point controlPoint3 = new Point();
24 | controlPoint3.set(center.x - pathWidth / 2, center.y + pathHeight);
25 | Point controlPoint4 = new Point();
26 | controlPoint4.set(center.x + pathWidth / 2, center.y - pathHeight);
27 | Path path = new Path();
28 | path.moveTo(center.x - pathWidth, center.y);
29 | path.cubicTo(controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y,
30 | center.x + pathWidth, center.y);
31 |
32 | path.cubicTo(controlPoint4.x, controlPoint4.y, controlPoint3.x, controlPoint3.y,
33 | center.x - pathWidth, center.y);
34 | return path;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/factory/path/Square.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs.factory.path;
2 |
3 | import android.graphics.Path;
4 | import android.graphics.Point;
5 |
6 | /**
7 | * @author Adrián García Lomas
8 | */
9 | public class Square extends BallPath {
10 |
11 | public Square(Point center, int pathWidth, int pathHeight, int maxBallSize) {
12 | super(center, pathWidth, pathHeight, maxBallSize);
13 | }
14 |
15 | @Override
16 | public Path draw() {
17 | Point startPoint = new Point(center.x - pathWidth / 2, center.y - pathHeight / 2);
18 | Point endPoint = new Point(center.x + pathWidth / 2, center.y + pathHeight / 2);
19 | Path path = new Path();
20 | path.addRect(startPoint.x + maxBallSize, startPoint.y + maxBallSize, endPoint.x - maxBallSize,
21 | endPoint.y - maxBallSize, Path.Direction.CCW);
22 | return path;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/factory/path/Star.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs.factory.path;
2 |
3 | import android.graphics.Path;
4 | import android.graphics.Point;
5 |
6 | /**
7 | * @author Adrián García Lomas
8 | */
9 | public class Star extends BallPath {
10 |
11 | public Star(Point center, int pathWidth, int pathHeight, int maxBallSize) {
12 | super(center, pathWidth, pathHeight, maxBallSize);
13 | }
14 |
15 | @Override
16 | public Path draw() {
17 | int squareWidth = pathHeight / 4;
18 | int middleSquare = squareWidth / 2;
19 |
20 | Point[] squarePoints = new Point[4];
21 | initializePoints(squarePoints);
22 | squarePoints[0].set(center.x - middleSquare, center.y - middleSquare);
23 | squarePoints[1].set(center.x + middleSquare, squarePoints[0].y);
24 | squarePoints[2].set(squarePoints[1].x, center.y + middleSquare);
25 | squarePoints[3].set(squarePoints[0].x, squarePoints[2].y);
26 |
27 | Point[] starPoints = new Point[4];
28 | initializePoints(starPoints);
29 | starPoints[0].set(maxBallSize, center.y);
30 | starPoints[1].set(center.x, maxBallSize);
31 | starPoints[2].set(pathWidth - maxBallSize, center.y);
32 | starPoints[3].set(center.x, pathHeight - maxBallSize);
33 |
34 | Path starPath = new Path();
35 |
36 | starPath.moveTo(starPoints[0].x, starPoints[0].y);
37 | starPath.lineTo(squarePoints[0].x, squarePoints[0].y);
38 |
39 | for (int i = 1; i < 4; i++) {
40 | starPath.lineTo(starPoints[i].x, starPoints[i].y);
41 | starPath.lineTo(squarePoints[i].x, squarePoints[i].y);
42 | }
43 |
44 | starPath.close();
45 |
46 | return starPath;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/loadingballs/src/main/java/com/github/glomadrian/loadingballs/factory/path/Triangle.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs.factory.path;
2 |
3 | import android.graphics.Path;
4 | import android.graphics.Point;
5 |
6 | /**
7 | * @author Adrián García Lomas
8 | */
9 | public class Triangle extends BallPath {
10 |
11 | public Triangle(Point center, int pathWidth, int pathHeight, int maxBallSize) {
12 | super(center, pathWidth, pathHeight, maxBallSize);
13 | }
14 |
15 | @Override
16 | public Path draw() {
17 | Path path = new Path();
18 | path.moveTo(maxBallSize, pathHeight - maxBallSize);
19 | path.lineTo(center.x, maxBallSize);
20 | path.lineTo(pathWidth - maxBallSize, pathHeight - maxBallSize);
21 | path.lineTo(maxBallSize, pathHeight - maxBallSize);
22 | return path;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/loadingballs/src/main/res/values/atrrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/loadingballs/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | LoadingBalls
3 |
4 |
--------------------------------------------------------------------------------
/loadingballs/src/test/java/com/github/glomadrian/loadingballs/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.github.glomadrian.loadingballs;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':loadingballs'
2 |
--------------------------------------------------------------------------------