├── .circleci └── config.yml ├── .gitignore ├── .idea ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── agrawalsuneet │ │ └── loaders │ │ ├── MainActivity.kt │ │ └── MainActivityJava.java │ └── res │ ├── drawable │ ├── ic_excel.xml │ ├── ic_launcher_background.xml │ ├── ic_pdf.xml │ ├── ic_photoshop.xml │ └── ic_text.xml │ ├── layout │ ├── activity_main_circular.xml │ ├── activity_main_circular_rotating.xml │ ├── activity_main_clock.xml │ ├── activity_main_multipleripple.xml │ ├── activity_main_ripple.xml │ ├── main_arcprogress.xml │ ├── main_curves.xml │ ├── main_fidget.xml │ ├── main_gauge.xml │ ├── main_pulse.xml │ ├── main_ringandcircle.xml │ ├── main_search.xml │ └── main_wifi.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── loaderspack ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── agrawalsuneet │ │ └── loaderspack │ │ ├── basicviews │ │ ├── ArcView.kt │ │ ├── CircleView.kt │ │ ├── CircularSticksBaseView.kt │ │ ├── FidgetView.kt │ │ ├── MagnifyingGlassView.kt │ │ └── NeedleView.kt │ │ ├── contracts │ │ ├── CircularSticksAbstractView.kt │ │ ├── LoaderContract.kt │ │ └── RippleAbstractView.kt │ │ ├── loaders │ │ ├── ArcProgressLoader.kt │ │ ├── CircularSticksLoader.kt │ │ ├── ClockLoader.kt │ │ ├── CurvesLoader.kt │ │ ├── FidgetLoader.kt │ │ ├── GaugeLoader.kt │ │ ├── MultipleRippleLoader.kt │ │ ├── PulseLoader.kt │ │ ├── RingAndCircleLoader.kt │ │ ├── RippleLoader.kt │ │ ├── RotatingCircularSticksLoader.kt │ │ ├── SearchLoader.kt │ │ └── WifiLoader.kt │ │ └── utils │ │ ├── Helper.kt │ │ └── Utils.kt │ └── res │ └── values │ └── attrs.xml └── settings.gradle /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | working_directory: ~/code 5 | docker: 6 | - image: circleci/android:api-25-alpha 7 | environment: 8 | JVM_OPTS: -Xmx3200m 9 | steps: 10 | - checkout 11 | - restore_cache: 12 | key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} 13 | # - run: 14 | # name: Chmod permissions #if permission for Gradlew Dependencies fail, use this. 15 | # command: sudo chmod +x ./gradlew 16 | 17 | - run: 18 | name: Approve license for build tools 19 | command: (echo y; echo y; echo y; echo y; echo y; echo y) | $ANDROID_HOME/tools/bin/sdkmanager --licenses 20 | 21 | - run: 22 | name: Download Dependencies 23 | command: ./gradlew androidDependencies 24 | - save_cache: 25 | paths: 26 | - ~/.gradle 27 | key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} 28 | - run: 29 | name: Run Tests 30 | command: ./gradlew lint test 31 | - store_artifacts: 32 | path: app/build/reports 33 | destination: reports 34 | - store_test_results: 35 | path: app/build/test-results 36 | # See https://circleci.com/docs/2.0/deployment-integrations/ for deploy examples -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/dictionaries 41 | .idea/libraries 42 | .iead/caches 43 | .idea/caches/build_file_checksums.ser 44 | 45 | # Keystore files 46 | *.jks 47 | 48 | # External native build folder generated in Android Studio 2.2 and later 49 | .externalNativeBuild 50 | 51 | # Google Services (e.g. APIs or Firebase) 52 | google-services.json 53 | 54 | # Freeline 55 | freeline.py 56 | freeline/ 57 | freeline_project_description.json 58 | 59 | *.DS_Store 60 | .idea/ -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 28 7 | buildToolsVersion '28.0.2' 8 | defaultConfig { 9 | applicationId "com.agrawalsuneet.loaders" 10 | minSdkVersion 16 11 | targetSdkVersion 28 12 | versionCode 1 13 | versionName "1.0" 14 | vectorDrawables.useSupportLibrary = true 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | implementation 'com.android.support:appcompat-v7:28.0.0' 26 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 27 | implementation project(':loaderspack') 28 | //implementation 'com.agrawalsuneet.androidlibs:loaderspack:1.0' 29 | implementation 'com.android.support.constraint:constraint-layout:1.0.2' 30 | } 31 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/agrawalsuneet/loaders/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaders 2 | 3 | import android.os.Bundle 4 | import android.os.Handler 5 | import android.support.v4.content.ContextCompat 6 | import android.support.v7.app.AppCompatActivity 7 | import android.view.animation.Animation 8 | import android.view.animation.BounceInterpolator 9 | import android.view.animation.LinearInterpolator 10 | import android.view.animation.RotateAnimation 11 | import android.widget.LinearLayout 12 | import com.agrawalsuneet.loaderspack.loaders.* 13 | 14 | class MainActivity : AppCompatActivity() { 15 | 16 | lateinit var containerLayout: LinearLayout 17 | 18 | override fun onCreate(savedInstanceState: Bundle?) { 19 | super.onCreate(savedInstanceState) 20 | setContentView(R.layout.activity_main_circular) 21 | 22 | supportActionBar?.setTitle("CurvesLoader") 23 | 24 | containerLayout = findViewById(R.id.container) 25 | 26 | //initClockLoader(); 27 | //initRippleLoader() 28 | //initRotatingCircularSticksLoader() 29 | //initCircularSticksLoader() 30 | 31 | //initMultipleRippleLoader() 32 | //initCurvesLoader() 33 | //initRingAndCircleLoader() 34 | //initArcProgressLoader() 35 | 36 | //initFidgetLoader() 37 | //initWifiLoader() 38 | //initPulseLoader() 39 | 40 | //initGaugeLoader() 41 | //initSearchLoader() 42 | } 43 | 44 | private fun initSearchLoader() { 45 | val searchLoader = SearchLoader(this, 46 | 60, 20, 80, 47 | ContextCompat.getColor(this, R.color.red), 48 | 500, 500, true) 49 | 50 | containerLayout.addView(searchLoader) 51 | } 52 | 53 | private fun initGaugeLoader() { 54 | /*val gaugeLoader = GaugeLoader(this, 150, 80, 55 | 20, 50, 56 | ContextCompat.getColor(this, R.color.blue_delfault), 57 | ContextCompat.getColor(this, R.color.blue_selected), 58 | ContextCompat.getColor(this, android.R.color.black), true)*/ 59 | 60 | val gaugeLoader = GaugeLoader(this, 150, 80, 61 | 20, 50, 62 | ContextCompat.getColor(this, R.color.blue_delfault), 63 | ContextCompat.getColor(this, R.color.blue_selected), 64 | ContextCompat.getColor(this, android.R.color.black), false) 65 | 66 | Handler().postDelayed({ 67 | val anim = RotateAnimation(270.0f, 450.0f, gaugeLoader.needlePivotX, gaugeLoader.needlePivotY) 68 | anim.duration = 1000 69 | anim.interpolator = LinearInterpolator() 70 | anim.repeatMode = Animation.REVERSE 71 | anim.repeatCount = Animation.INFINITE 72 | gaugeLoader.startLoading(anim) 73 | }, 500) 74 | 75 | containerLayout.addView(gaugeLoader) 76 | } 77 | 78 | private fun initPulseLoader() { 79 | val pulseLoader = PulseLoader(this, 80 | 15, 81 | 400, 82 | 4.0f, 83 | 15.0f, 84 | ContextCompat.getColor(this, R.color.blue_selected)) 85 | 86 | containerLayout.addView(pulseLoader) 87 | } 88 | 89 | private fun initWifiLoader() { 90 | val wifiLoader = WifiLoader(this, 91 | 20, 92 | ContextCompat.getColor(this, R.color.blue_selected)) 93 | .apply { 94 | incrementalAngle = 2.0f 95 | } 96 | 97 | containerLayout.addView(wifiLoader) 98 | } 99 | 100 | private fun initFidgetLoader() { 101 | val fidgetLoader = FidgetLoader(this, 102 | 20, 103 | ContextCompat.getColor(this, R.color.blue_selected), 104 | ContextCompat.getColor(this, R.color.amber)) 105 | .apply { 106 | animDuration = 3000 107 | noOfRotation = 1 108 | interpolator = BounceInterpolator() 109 | } 110 | 111 | containerLayout.addView(fidgetLoader) 112 | } 113 | 114 | private fun initArcProgressLoader() { 115 | val arcProgressLoader = ArcProgressLoader(this, 116 | 120, 20, 117 | 10.0f, 180.0f, 118 | resources.getIntArray(R.array.colors_rgb)) 119 | 120 | containerLayout.addView(arcProgressLoader) 121 | 122 | } 123 | 124 | private fun initRingAndCircleLoader() { 125 | val ringAndCircleLoader = RingAndCircleLoader( 126 | this, 127 | 20, 128 | 100, 129 | 10, 130 | ContextCompat.getColor(this, R.color.blue), 131 | ContextCompat.getColor(this, R.color.blue_delfault)) 132 | .apply { 133 | animDuration = 1000 134 | } 135 | 136 | containerLayout.addView(ringAndCircleLoader) 137 | } 138 | 139 | private fun initCurvesLoader() { 140 | val curvesLoader = CurvesLoader( 141 | this, 142 | 4, 143 | 100, 144 | 10, 145 | 10, 146 | 160.0f, 147 | ContextCompat.getColor(this, R.color.blue_selected)) 148 | .apply { 149 | animDuration = 1000 150 | interpolator = LinearInterpolator() 151 | } 152 | 153 | containerLayout.addView(curvesLoader) 154 | } 155 | 156 | private fun initMultipleRippleLoader() { 157 | val multipleRippleLoader = MultipleRippleLoader(this, 158 | 40, 159 | ContextCompat.getColor(this, R.color.blue), 160 | 2) 161 | .apply { 162 | fromAlpha = 0.9f 163 | toAlpha = 0.2f 164 | animationDuration = 2000 165 | interpolator = LinearInterpolator() 166 | } 167 | 168 | containerLayout.addView(multipleRippleLoader) 169 | } 170 | 171 | private fun initCircularSticksLoader() { 172 | val loader = CircularSticksLoader(this, 16, 200f, 100f, 173 | ContextCompat.getColor(this, R.color.blue), 174 | ContextCompat.getColor(this, R.color.red), 175 | ContextCompat.getColor(this, android.R.color.white)) 176 | .apply { 177 | showRunningShadow = true 178 | firstShadowColor = ContextCompat.getColor(context, R.color.green) 179 | secondShadowColor = ContextCompat.getColor(context, R.color.yellow) 180 | animDuration = 100 181 | } 182 | 183 | containerLayout.addView(loader) 184 | } 185 | 186 | private fun initRotatingCircularSticksLoader() { 187 | val loader = RotatingCircularSticksLoader(this, 16, 100f, 50f, 188 | ContextCompat.getColor(this, R.color.blue), 189 | ContextCompat.getColor(this, android.R.color.white)) 190 | .apply { 191 | animDuration = 5000 192 | } 193 | 194 | containerLayout.addView(loader) 195 | } 196 | 197 | private fun initRippleLoader() { 198 | val ripple = RippleLoader(baseContext)/*.apply { 199 | circleInitialRadius = 80 200 | wifiColor = resources.getColor(R.color.black) 201 | fromAlpha = 1.0f 202 | toAlpha = 0f 203 | animationDuration = 1000 204 | interpolator = DecelerateInterpolator() 205 | }*/ 206 | 207 | containerLayout.addView(ripple) 208 | } 209 | 210 | private fun initClockLoader() { 211 | var clock = ClockLoader(this) 212 | /*.apply { 213 | outerCircleBorderWidth = 10.0f 214 | bigCircleRadius = 200.0f 215 | minuteHandLength = 150.0f 216 | hourHandLength = 100.0f 217 | innerCircleRadius = 30.0f 218 | 219 | outerCircleBorderColor = ContextCompat.getColor(context, R.color.colorAccent) 220 | bigCircleColor = ContextCompat.getColor(context, R.color.colorPrimary) 221 | innerCircleColor = ContextCompat.getColor(context, R.color.colorPrimaryDark) 222 | hourHandColor = ContextCompat.getColor(context, R.color.colorAccent) 223 | minuteHandColor = ContextCompat.getColor(context, R.color.colorAccent) 224 | 225 | animSpeedMultiplier = 2.0f 226 | }*/ 227 | 228 | 229 | containerLayout.addView(clock) 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /app/src/main/java/com/agrawalsuneet/loaders/MainActivityJava.java: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaders; 2 | 3 | import android.os.Bundle; 4 | import android.os.Handler; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.content.ContextCompat; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.view.animation.Animation; 9 | import android.view.animation.LinearInterpolator; 10 | import android.view.animation.RotateAnimation; 11 | import android.widget.LinearLayout; 12 | 13 | import com.agrawalsuneet.loaderspack.loaders.GaugeLoader; 14 | import com.agrawalsuneet.loaderspack.loaders.SearchLoader; 15 | 16 | /** 17 | * Created by suneet on 10/31/17. 18 | */ 19 | 20 | public class MainActivityJava extends AppCompatActivity { 21 | 22 | LinearLayout container; 23 | 24 | @Override 25 | protected void onCreate(@Nullable Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | 28 | setContentView(R.layout.activity_main_clock); 29 | 30 | 31 | /*//Clock Loader 32 | ClockLoader clockLoader = new ClockLoader(this); 33 | clockLoader.setOuterCircleBorderWidth(8.0f); 34 | clockLoader.setBigCircleRadius(150.0f); 35 | clockLoader.setMinuteHandLength(120.0f); 36 | clockLoader.setHourHandLength(80.0f); 37 | clockLoader.setInnerCircleRadius(15.0f); 38 | 39 | clockLoader.setOuterCircleBorderColor(ContextCompat.getColor(this, R.color.colorAccent)); 40 | clockLoader.setBigCircleColor(ContextCompat.getColor(this, R.color.colorPrimary)); 41 | clockLoader.setInnerCircleColor(ContextCompat.getColor(this, R.color.colorPrimaryDark)); 42 | clockLoader.setHourHandColor(ContextCompat.getColor(this, R.color.colorAccent)); 43 | clockLoader.setMinuteHandColor(ContextCompat.getColor(this, R.color.colorAccent)); 44 | 45 | clockLoader.setAnimSpeedMultiplier(2.0f); 46 | 47 | container.addView(clockLoader); 48 | 49 | //RotatingCircularSticksLoader 50 | RotatingCircularSticksLoader loader = new RotatingCircularSticksLoader(this, 51 | 16, 100f, 50f, 52 | ContextCompat.getColor(this, R.color.blue), 53 | ContextCompat.getColor(this, android.R.color.white)); 54 | 55 | loader.setAnimDuration(5000); 56 | container.addView(loader); 57 | 58 | 59 | //CircularSticksLoader 60 | *//*CircularSticksLoader loader = new CircularSticksLoader(this, 16, 61 | 200f, 100f, 62 | ContextCompat.getColor(this, R.color.blue), 63 | ContextCompat.getColor(this, R.color.red), 64 | ContextCompat.getColor(this, android.R.color.white)); 65 | 66 | loader.setShowRunningShadow(true); 67 | loader.setFirstShadowColor(ContextCompat.getColor(this, R.color.green)); 68 | loader.setSecondShadowColor(ContextCompat.getColor(this, R.color.yellow)); 69 | loader.setAnimDuration(100); 70 | 71 | container.addView(loader);*//* 72 | 73 | 74 | //MultipleRippleLoader 75 | MultipleRippleLoader multipleRippleLoader = new MultipleRippleLoader(this, 76 | 40, 77 | ContextCompat.getColor(this, R.color.blue), 78 | 2); 79 | 80 | multipleRippleLoader.setFromAlpha(0.9f); 81 | multipleRippleLoader.setToAlpha(0.2f); 82 | multipleRippleLoader.setAnimationDuration(2000); 83 | multipleRippleLoader.setInterpolator(new LinearInterpolator()); 84 | 85 | 86 | container.addView(multipleRippleLoader); 87 | 88 | CurvesLoader curvesLoader = new CurvesLoader( 89 | this, 90 | 4, 91 | 100, 92 | 10, 93 | 10, 94 | 160.0f, 95 | ContextCompat.getColor(this, R.color.blue_selected)); 96 | 97 | 98 | curvesLoader.setAnimDuration(1000); 99 | curvesLoader.setInterpolator(new LinearInterpolator()); 100 | 101 | container.addView(curvesLoader); 102 | 103 | 104 | RingAndCircleLoader ringAndCircleLoader = new RingAndCircleLoader( 105 | this, 106 | 20, 107 | 100, 108 | 10, 109 | ContextCompat.getColor(this, R.color.blue), 110 | ContextCompat.getColor(this, R.color.blue_delfault)); 111 | 112 | ringAndCircleLoader.setAnimDuration(1000); 113 | 114 | container.addView(ringAndCircleLoader); 115 | 116 | 117 | ArcProgressLoader arcProgressLoader = new ArcProgressLoader(this, 118 | 120, 20, 119 | 10.0f, 180.0f, 120 | getResources().getIntArray(R.array.colors_rgb)); 121 | 122 | container.addView(arcProgressLoader);*/ 123 | 124 | 125 | /*FidgetLoader fidgetLoader = new FidgetLoader(this, 126 | 20, 127 | ContextCompat.getColor(this, R.color.blue_selected), 128 | ContextCompat.getColor(this, R.color.amber)); 129 | 130 | fidgetLoader.setAnimDuration(3000); 131 | fidgetLoader.setNoOfRotation(1); 132 | fidgetLoader.setInterpolator(new BounceInterpolator()); 133 | 134 | container.addView(fidgetLoader);*/ 135 | 136 | /*WifiLoader wifiLoader = new WifiLoader(this, 137 | 20, 138 | ContextCompat.getColor(this, R.color.blue_selected)); 139 | 140 | wifiLoader.setIncrementalAngle(1.2f); 141 | 142 | container.addView(wifiLoader);*/ 143 | 144 | /*PulseLoader pulseLoader = new PulseLoader(this, 145 | 15, 146 | 400, 147 | 4.0f, 148 | 15.0f, 149 | ContextCompat.getColor(this, R.color.blue_selected)); 150 | 151 | container.addView(pulseLoader);*/ 152 | 153 | 154 | /*GaugeLoader gaugeLoader = new GaugeLoader(this, 150, 80, 155 | 20, 50, 156 | ContextCompat.getColor(this, R.color.blue_delfault), 157 | ContextCompat.getColor(this, R.color.blue_selected), 158 | ContextCompat.getColor(this, android.R.color.black), true); 159 | 160 | container.addView(gaugeLoader); 161 | 162 | //or you can provide custom rotate animation for needle*/ 163 | 164 | /*final GaugeLoader gaugeLoader = new GaugeLoader(this, 150, 80, 165 | 20, 50, 166 | ContextCompat.getColor(this, R.color.blue_delfault), 167 | ContextCompat.getColor(this, R.color.blue_selected), 168 | ContextCompat.getColor(this, android.R.color.black), false); 169 | 170 | new Handler().postDelayed(new Runnable() { 171 | @Override 172 | public void run() { 173 | RotateAnimation anim = new RotateAnimation(270.0f, 450.0f, 174 | gaugeLoader.getNeedlePivotX(), gaugeLoader.getNeedlePivotY()); 175 | anim.setDuration(1000); 176 | anim.setInterpolator(new LinearInterpolator()); 177 | anim.setRepeatMode(Animation.REVERSE); 178 | anim.setRepeatCount(Animation.INFINITE); 179 | gaugeLoader.startLoading(anim); 180 | } 181 | }, 500); 182 | 183 | //delay because view will not be initialized 184 | 185 | container.addView(gaugeLoader);*/ 186 | 187 | 188 | SearchLoader searchLoader = new SearchLoader(this, 189 | 60, 20, 80, 190 | ContextCompat.getColor(this, R.color.red), 191 | 500, 500, true); 192 | 193 | container.addView(searchLoader); 194 | 195 | } 196 | 197 | 198 | } 199 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_excel.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 12 | 17 | 22 | 27 | 32 | 37 | 42 | 47 | 52 | 57 | 62 | 67 | 72 | 77 | 82 | 87 | 92 | 97 | 102 | 107 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pdf.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_photoshop.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_text.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main_circular.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 17 | 18 | 32 | 33 | 47 | 48 | 62 | 63 | 64 | 65 | 66 | 67 | 79 | 80 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main_circular_rotating.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 17 | 18 | 28 | 29 | 39 | 40 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 75 | 76 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main_clock.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 28 | 29 | 30 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main_multipleripple.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 27 | 28 | 29 | 41 | 42 | 52 | 53 | 54 | 55 | 60 | 61 | 72 | 73 | 79 | 80 | 81 | 82 | 83 | 88 | 89 | 100 | 101 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main_ripple.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | 16 | 34 | 35 | 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_arcprogress.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 25 | 26 | 27 | 36 | 37 | 46 | 47 | 48 | 49 | 50 | 59 | 60 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_curves.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 28 | 29 | 40 | 41 | 52 | 53 | 54 | 55 | 67 | 68 | 69 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_fidget.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 26 | 27 | 37 | 38 | 48 | 49 | 50 | 51 | 52 | 62 | 63 | 64 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_gauge.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 28 | 29 | 40 | 41 | 53 | 54 | 55 | 56 | 57 | 68 | 69 | 70 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_pulse.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 24 | 25 | 26 | 35 | 36 | 45 | 46 | 47 | 48 | 49 | 58 | 59 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_ringandcircle.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 26 | 27 | 37 | 38 | 48 | 49 | 50 | 51 | 52 | 53 | 63 | 64 | 65 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_search.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 19 | 20 | 25 | 26 | 36 | 37 | 38 | 39 | 43 | 44 | 49 | 50 | 60 | 61 | 62 | 63 | 64 | 68 | 69 | 74 | 75 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 95 | 96 | 101 | 102 | 112 | 113 | 114 | 115 | 116 | 120 | 121 | 126 | 127 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_wifi.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 23 | 24 | 31 | 32 | 33 | 40 | 41 | 42 | 43 | 44 | 45 | 52 | 53 | 54 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | #ffffff 8 | #ff0000 9 | #77ff0000 10 | #00e500 11 | #7700e500 12 | #ffff00 13 | #FFC200 14 | #77FFC200 15 | 16 | #0000ff 17 | #2196F3 18 | #BBDEFB 19 | 20 | #55A9A9A9 21 | 22 | #8B008B 23 | 24 | 25 | @color/red 26 | 27 | 28 | 29 | @color/amber 30 | 31 | 32 | 33 | @color/green 34 | 35 | 36 | 37 | @color/red 38 | @color/amber 39 | @color/green 40 | @android:color/darker_gray 41 | 42 | 43 | 44 | @color/blue_selected 45 | @color/blue_delfault 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Loaders 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.2.51' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.2.0' 9 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 10 | 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 | google() 19 | jcenter() 20 | } 21 | } 22 | 23 | task clean(type: Delete) { 24 | delete rootProject.buildDir 25 | } 26 | -------------------------------------------------------------------------------- /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 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agrawalsuneet/LoadersPack-Android/1acf30bbd693d7143ddf5ffc52421b4b90071aef/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Sep 05 13:50:45 BST 2018 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-4.6-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 | -------------------------------------------------------------------------------- /loaderspack/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /loaderspack/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | 4 | repositories { 5 | mavenCentral() 6 | } 7 | 8 | ext { 9 | PUBLISH_GROUP_ID = 'com.agrawalsuneet.androidlibs' 10 | PUBLISH_ARTIFACT_ID = 'loaderspack' 11 | PUBLISH_VERSION = '1.2.3' 12 | } 13 | 14 | android { 15 | compileSdkVersion 28 16 | 17 | defaultConfig { 18 | minSdkVersion 16 19 | targetSdkVersion 28 20 | versionCode 15 21 | versionName "1.2.3" 22 | } 23 | 24 | buildTypes { 25 | release { 26 | minifyEnabled false 27 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 28 | } 29 | } 30 | 31 | } 32 | 33 | dependencies { 34 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 35 | } 36 | 37 | apply from: 'https://raw.githubusercontent.com/blundell/release-android-library/master/android-release-aar.gradle' -------------------------------------------------------------------------------- /loaderspack/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /loaderspack/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/basicviews/ArcView.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.basicviews 2 | 3 | import android.content.Context 4 | import android.graphics.Canvas 5 | import android.graphics.Paint 6 | import android.graphics.RectF 7 | import android.util.AttributeSet 8 | import android.view.View 9 | import com.agrawalsuneet.loaderspack.R 10 | 11 | /** 12 | * Created by agrawalsuneet on 9/4/18. 13 | */ 14 | 15 | class ArcView : View { 16 | 17 | var arcRadius: Int = 60 18 | var arcWidth: Int = 10 19 | 20 | var startAngle: Float = 0.0f 21 | 22 | var sweepAngle: Float = 180.0f 23 | 24 | var arcColor: Int = resources.getColor(android.R.color.holo_red_dark) 25 | var drawOnlyStroke: Boolean = true 26 | 27 | var roundedEdges: Boolean = true 28 | 29 | private val paint: Paint = Paint() 30 | private var centerPoint: Float = 0.0f 31 | private var acrRect = RectF() 32 | 33 | constructor(context: Context, arcRadius: Int, arcWidth: Int, 34 | startAngle: Float, sweepAngle: 35 | Float, arcColor: Int, drawOnlyStroke: Boolean, 36 | roundedEdges: Boolean = true) : super(context) { 37 | this.arcRadius = arcRadius 38 | this.arcWidth = arcWidth 39 | this.startAngle = startAngle 40 | this.sweepAngle = sweepAngle 41 | this.arcColor = arcColor 42 | this.drawOnlyStroke = drawOnlyStroke 43 | this.roundedEdges = roundedEdges 44 | 45 | initValues() 46 | } 47 | 48 | constructor(context: Context) : super(context) { 49 | initValues() 50 | } 51 | 52 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 53 | initAttributes(attrs) 54 | initValues() 55 | } 56 | 57 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 58 | initAttributes(attrs) 59 | initValues() 60 | } 61 | 62 | 63 | fun initAttributes(attrs: AttributeSet) { 64 | 65 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ArcView, 0, 0) 66 | 67 | this.arcRadius = typedArray.getDimensionPixelSize(R.styleable.ArcView_arcRadius, 60) 68 | this.arcWidth = typedArray.getDimensionPixelSize(R.styleable.ArcView_arcWidth, 10) 69 | 70 | this.startAngle = typedArray.getFloat(R.styleable.ArcView_startAngle, 0.0f) 71 | this.sweepAngle = typedArray.getFloat(R.styleable.ArcView_sweepAngle, 180.0f) 72 | 73 | this.arcColor = typedArray.getColor(R.styleable.ArcView_arcColor, resources.getColor(android.R.color.holo_red_dark)) 74 | 75 | this.drawOnlyStroke = typedArray.getBoolean(R.styleable.ArcView_drawOnlyStroke, true) 76 | 77 | typedArray.recycle() 78 | } 79 | 80 | private fun initValues() { 81 | centerPoint = (arcRadius + (arcWidth / 2)).toFloat() 82 | 83 | acrRect = RectF().apply { 84 | left = centerPoint - arcRadius 85 | right = centerPoint + arcRadius 86 | top = centerPoint - arcRadius 87 | bottom = centerPoint + arcRadius 88 | } 89 | } 90 | 91 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 92 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 93 | 94 | val widthHeight = (2 * (arcRadius)) + arcWidth 95 | setMeasuredDimension(widthHeight, widthHeight) 96 | } 97 | 98 | 99 | override fun onDraw(canvas: Canvas) { 100 | super.onDraw(canvas) 101 | 102 | paint.isAntiAlias = true 103 | 104 | if (drawOnlyStroke) { 105 | paint.style = Paint.Style.STROKE 106 | paint.strokeWidth = arcWidth.toFloat() 107 | if (roundedEdges) { 108 | paint.strokeCap = Paint.Cap.ROUND 109 | } 110 | } else { 111 | paint.style = Paint.Style.FILL 112 | } 113 | paint.color = arcColor 114 | 115 | canvas.drawArc(acrRect, startAngle, sweepAngle, false, paint) 116 | } 117 | 118 | 119 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/basicviews/CircleView.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.basicviews 2 | 3 | import android.content.Context 4 | import android.graphics.Canvas 5 | import android.graphics.Paint 6 | import android.util.AttributeSet 7 | import android.view.View 8 | import com.agrawalsuneet.loaderspack.R 9 | 10 | /** 11 | * Created by suneet on 11/15/17. 12 | */ 13 | 14 | 15 | class CircleView : View { 16 | 17 | var circleRadius: Int = 30 18 | var strokeWidth: Int = 0 19 | 20 | var circleColor: Int = resources.getColor(android.R.color.holo_red_light) 21 | var drawOnlyStroke: Boolean = false 22 | 23 | private val paint: Paint = Paint() 24 | 25 | constructor(context: Context, circleRadius: Int, circleColor: Int) : super(context) { 26 | this.circleRadius = circleRadius 27 | this.circleColor = circleColor 28 | } 29 | 30 | constructor(context: Context, circleRadius: Int, circleColor: Int, drawOnlyStroke: Boolean, strokeWidth: Int) : super(context) { 31 | this.circleRadius = circleRadius 32 | this.circleColor = circleColor 33 | 34 | this.drawOnlyStroke = drawOnlyStroke 35 | this.strokeWidth = strokeWidth 36 | } 37 | 38 | constructor(context: Context) : super(context) 39 | 40 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 41 | initAttributes(attrs) 42 | } 43 | 44 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 45 | initAttributes(attrs) 46 | } 47 | 48 | 49 | fun initAttributes(attrs: AttributeSet) { 50 | 51 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleView, 0, 0) 52 | 53 | this.circleRadius = typedArray.getDimensionPixelSize(R.styleable.CircleView_circleRadius, 30) 54 | this.circleColor = typedArray.getColor(R.styleable.CircleView_circleColor, resources.getColor(android.R.color.holo_red_light)) 55 | 56 | this.drawOnlyStroke = typedArray.getBoolean(R.styleable.CircleView_circleDrawOnlystroke, false) 57 | 58 | if (drawOnlyStroke) { 59 | this.strokeWidth = typedArray.getDimensionPixelSize(R.styleable.CircleView_circleStrokeWidth, 0) 60 | } 61 | 62 | typedArray.recycle() 63 | } 64 | 65 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 66 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 67 | 68 | val widthHeight = (2 * (circleRadius)) + strokeWidth 69 | setMeasuredDimension(widthHeight, widthHeight) 70 | } 71 | 72 | 73 | override fun onDraw(canvas: Canvas?) { 74 | super.onDraw(canvas) 75 | 76 | paint.isAntiAlias = true 77 | 78 | if (drawOnlyStroke) { 79 | paint.style = Paint.Style.STROKE 80 | paint.strokeWidth = strokeWidth.toFloat() 81 | } else { 82 | paint.style = Paint.Style.FILL 83 | } 84 | paint.color = circleColor 85 | 86 | //adding half of arcWidth because 87 | //the stroke will be half inside the drawing circle and half outside 88 | val xyCordinates = (circleRadius + (strokeWidth / 2)).toFloat() 89 | 90 | canvas!!.drawCircle(xyCordinates, xyCordinates, circleRadius.toFloat(), paint) 91 | } 92 | 93 | 94 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/basicviews/CircularSticksBaseView.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.basicviews 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import com.agrawalsuneet.loaderspack.R 6 | import com.agrawalsuneet.loaderspack.contracts.CircularSticksAbstractView 7 | 8 | /** 9 | * Created by suneet on 12/31/17. 10 | */ 11 | 12 | class CircularSticksBaseView : CircularSticksAbstractView { 13 | 14 | constructor(context: Context) : super(context) { 15 | initPaints() 16 | } 17 | 18 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 19 | initAttributes(attrs) 20 | initPaints() 21 | } 22 | 23 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 24 | initAttributes(attrs) 25 | initPaints() 26 | } 27 | 28 | constructor(context: Context, noOfSticks: Int, outerCircleRadius: Float, innerCircleRadius: Float, sticksColor: Int, viewBackgroundColor: Int) : super(context) { 29 | this.noOfSticks = noOfSticks 30 | this.outerCircleRadius = outerCircleRadius 31 | this.innerCircleRadius = innerCircleRadius 32 | this.sticksColor = sticksColor 33 | this.viewBackgroundColor = viewBackgroundColor 34 | initPaints() 35 | } 36 | 37 | override fun initAttributes(attrs: AttributeSet) { 38 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularSticksBaseView, 0, 0) 39 | 40 | this.noOfSticks = typedArray 41 | .getInteger(R.styleable.CircularSticksBaseView_sticksbase_noOfSticks, 80) 42 | 43 | this.outerCircleRadius = typedArray 44 | .getDimension(R.styleable.CircularSticksBaseView_sticksbase_outerCircleRadius, 200.0f) 45 | this.innerCircleRadius = typedArray 46 | .getDimension(R.styleable.CircularSticksBaseView_sticksbase_innerCircleRadius, 100.0f) 47 | 48 | 49 | this.sticksColor = typedArray 50 | .getColor(R.styleable.CircularSticksBaseView_sticksbase_stickColor, resources.getColor(android.R.color.darker_gray)) 51 | this.viewBackgroundColor = typedArray 52 | .getColor(R.styleable.CircularSticksBaseView_sticksbase_viewBackgroundColor, resources.getColor(android.R.color.white)) 53 | 54 | typedArray.recycle() 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/basicviews/FidgetView.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.basicviews 2 | 3 | import android.content.Context 4 | import android.graphics.Canvas 5 | import android.graphics.Paint 6 | import android.util.AttributeSet 7 | import android.view.View 8 | import com.agrawalsuneet.loaderspack.R 9 | 10 | /** 11 | * Created by agrawalsuneet on 9/20/18. 12 | */ 13 | 14 | class FidgetView : View { 15 | 16 | companion object { 17 | const val distanceFactor = 0.8 18 | } 19 | 20 | var fidgetRadius: Int = 100 21 | var bodyColor: Int = resources.getColor(android.R.color.holo_red_light) 22 | var sideCirclesColor = resources.getColor(android.R.color.darker_gray) 23 | 24 | private val centerPaint: Paint = Paint() 25 | private val sidesPaint: Paint = Paint() 26 | 27 | private var calWidthHeight = 0.0f 28 | 29 | private val sin30 = 0.5 30 | private val cos30 = 0.866 31 | 32 | constructor(context: Context) : super(context) { 33 | initValues() 34 | } 35 | 36 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 37 | initAttributes(attrs) 38 | initValues() 39 | } 40 | 41 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 42 | initAttributes(attrs) 43 | initValues() 44 | } 45 | 46 | constructor(context: Context, fidgetRadius: Int, bodyColor: Int, sideCirclesColor: Int) : super(context) { 47 | this.fidgetRadius = fidgetRadius 48 | this.bodyColor = bodyColor 49 | this.sideCirclesColor = sideCirclesColor 50 | initValues() 51 | } 52 | 53 | 54 | fun initAttributes(attrs: AttributeSet) { 55 | 56 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.FidgetView, 0, 0) 57 | 58 | fidgetRadius = typedArray.getDimensionPixelSize(R.styleable.FidgetView_fidgetRadius, 100) 59 | bodyColor = typedArray.getColor(R.styleable.FidgetView_fidgetBodyColor, resources.getColor(android.R.color.holo_red_light)) 60 | sideCirclesColor = typedArray.getColor(R.styleable.FidgetView_fidgetSideCirclesColor, resources.getColor(android.R.color.darker_gray)) 61 | 62 | typedArray.recycle() 63 | } 64 | 65 | private fun initValues() { 66 | 67 | centerPaint.isAntiAlias = true 68 | centerPaint.style = Paint.Style.FILL 69 | centerPaint.color = bodyColor 70 | 71 | sidesPaint.isAntiAlias = true 72 | sidesPaint.style = Paint.Style.FILL 73 | sidesPaint.color = sideCirclesColor 74 | } 75 | 76 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 77 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 78 | 79 | calWidthHeight = (2 * fidgetRadius) + (4 * distanceFactor * (fidgetRadius)).toFloat() 80 | setMeasuredDimension(calWidthHeight.toInt(), calWidthHeight.toInt()) 81 | } 82 | 83 | 84 | override fun onDraw(canvas: Canvas) { 85 | super.onDraw(canvas) 86 | 87 | val centerXY = (calWidthHeight / 2) 88 | 89 | //center circle 90 | canvas.drawCircle(centerXY, centerXY, fidgetRadius.toFloat(), centerPaint) 91 | 92 | //top circle 93 | var xCor = calWidthHeight / 2 94 | var yCor = (centerXY - ((2 * fidgetRadius) * distanceFactor)).toFloat() 95 | 96 | canvas.drawCircle(xCor, yCor, fidgetRadius.toFloat(), centerPaint) 97 | canvas.drawCircle(xCor, yCor, (fidgetRadius * 3 / 5).toFloat(), sidesPaint) 98 | 99 | //right circle 100 | xCor = centerXY + (cos30 * distanceFactor * (2 * fidgetRadius)).toFloat() 101 | yCor = centerXY + (sin30 * distanceFactor * (2 * fidgetRadius)).toFloat() 102 | 103 | canvas.drawCircle(xCor, yCor, fidgetRadius.toFloat(), centerPaint) 104 | canvas.drawCircle(xCor, yCor, (fidgetRadius * 3 / 5).toFloat(), sidesPaint) 105 | 106 | //left circle 107 | xCor = centerXY - (cos30 * distanceFactor * (2 * fidgetRadius)).toFloat() 108 | yCor = centerXY + (sin30 * distanceFactor * (2 * fidgetRadius)).toFloat() 109 | 110 | canvas.drawCircle(xCor, yCor, fidgetRadius.toFloat(), centerPaint) 111 | canvas.drawCircle(xCor, yCor, (fidgetRadius * 3 / 5).toFloat(), sidesPaint) 112 | 113 | pivotX = centerXY 114 | pivotY = centerXY 115 | } 116 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/basicviews/MagnifyingGlassView.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.basicviews 2 | 3 | import android.content.Context 4 | import android.graphics.Canvas 5 | import android.graphics.Paint 6 | import android.util.AttributeSet 7 | import android.view.View 8 | import com.agrawalsuneet.loaderspack.R 9 | 10 | /** 11 | * Created by agrawalsuneet on 11/1/18. 12 | */ 13 | 14 | class MagnifyingGlassView : View { 15 | 16 | var glassRadius: Int = 50 17 | var glassBorderWidth: Int = 20 18 | 19 | var glassHandleLength: Int = 80 20 | 21 | var glassColor: Int = resources.getColor(android.R.color.holo_green_light) 22 | 23 | private val paint: Paint = Paint() 24 | 25 | private var circleCenterPoint: Float = 0.0f 26 | private var handleStartPoint: Float = 0.0f 27 | private var handleEndPoint: Float = 0.0f 28 | 29 | private val sin45 = 0.7075f 30 | 31 | constructor(context: Context) : super(context) { 32 | initValues() 33 | } 34 | 35 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 36 | initAttributes(attrs) 37 | initValues() 38 | } 39 | 40 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 41 | initAttributes(attrs) 42 | initValues() 43 | } 44 | 45 | constructor(context: Context?, glassRadius: Int, glassBorderWidth: Int, glassHandleLength: Int, glassColor: Int) : super(context) { 46 | this.glassRadius = glassRadius 47 | this.glassBorderWidth = glassBorderWidth 48 | this.glassHandleLength = glassHandleLength 49 | this.glassColor = glassColor 50 | initValues() 51 | } 52 | 53 | fun initAttributes(attrs: AttributeSet) { 54 | 55 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.MagnifyingGlassView, 0, 0) 56 | 57 | this.glassRadius = typedArray.getDimensionPixelSize(R.styleable.MagnifyingGlassView_glassRadius, 50) 58 | this.glassBorderWidth = typedArray.getDimensionPixelSize(R.styleable.MagnifyingGlassView_glassBorderWidth, 20) 59 | 60 | this.glassHandleLength = typedArray.getDimensionPixelSize(R.styleable.MagnifyingGlassView_glassHandleLength, 80) 61 | 62 | this.glassColor = typedArray.getColor(R.styleable.MagnifyingGlassView_glassColor, 63 | resources.getColor(android.R.color.holo_green_light)) 64 | 65 | typedArray.recycle() 66 | } 67 | 68 | private fun initValues() { 69 | 70 | paint.color = glassColor 71 | paint.isAntiAlias = true 72 | paint.strokeWidth = glassBorderWidth.toFloat() 73 | 74 | paint.strokeCap = Paint.Cap.ROUND 75 | 76 | circleCenterPoint = (glassRadius + glassBorderWidth / 2).toFloat() 77 | handleStartPoint = (circleCenterPoint + (glassRadius * sin45)) 78 | 79 | handleEndPoint = (handleStartPoint + (glassHandleLength * sin45)) 80 | 81 | } 82 | 83 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 84 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 85 | 86 | val widthHeight = ((2 * glassRadius) + (glassBorderWidth) 87 | + (glassHandleLength * sin45) - (0.29 * (glassRadius))).toInt() 88 | 89 | setMeasuredDimension(widthHeight, widthHeight) 90 | } 91 | 92 | 93 | override fun onDraw(canvas: Canvas) { 94 | super.onDraw(canvas) 95 | 96 | paint.style = Paint.Style.STROKE 97 | canvas.drawCircle(circleCenterPoint, 98 | circleCenterPoint, 99 | glassRadius.toFloat(), 100 | paint) 101 | 102 | paint.style = Paint.Style.FILL 103 | 104 | canvas.drawLine(handleStartPoint, handleStartPoint, 105 | handleEndPoint, handleEndPoint, 106 | paint) 107 | } 108 | 109 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/basicviews/NeedleView.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.basicviews 2 | 3 | import android.content.Context 4 | import android.graphics.Canvas 5 | import android.graphics.Paint 6 | import android.util.AttributeSet 7 | import android.view.View 8 | import com.agrawalsuneet.loaderspack.R 9 | 10 | class NeedleView : View { 11 | 12 | var needleLength: Int = 160 13 | var needleWidth: Int = 20 14 | var needleJointRadius: Int = 40 15 | 16 | var needleColor: Int = resources.getColor(android.R.color.holo_red_dark) 17 | 18 | private val paint: Paint = Paint() 19 | 20 | constructor(context: Context, needleLength: Int, needleWidth: Int, needleJointRadius: Int, needleColor: Int) : super(context) { 21 | this.needleLength = needleLength 22 | this.needleWidth = needleWidth 23 | this.needleJointRadius = needleJointRadius 24 | this.needleColor = needleColor 25 | initValues() 26 | } 27 | 28 | constructor(context: Context) : super(context) { 29 | initValues() 30 | } 31 | 32 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 33 | initAttributes(attrs) 34 | initValues() 35 | } 36 | 37 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 38 | initAttributes(attrs) 39 | initValues() 40 | } 41 | 42 | fun initAttributes(attrs: AttributeSet) { 43 | 44 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.NeedleView, 0, 0) 45 | 46 | this.needleLength = typedArray.getDimensionPixelSize(R.styleable.NeedleView_needleLength, 160) 47 | this.needleWidth = typedArray.getDimensionPixelSize(R.styleable.NeedleView_needleWidth, 20) 48 | 49 | this.needleJointRadius = typedArray.getDimensionPixelSize(R.styleable.NeedleView_needleJointRadius, 40) 50 | 51 | this.needleColor = typedArray.getColor(R.styleable.NeedleView_needleColor, resources.getColor(android.R.color.holo_red_dark)) 52 | typedArray.recycle() 53 | } 54 | 55 | private fun initValues() { 56 | paint.isAntiAlias = true 57 | paint.style = Paint.Style.FILL 58 | paint.strokeWidth = needleWidth.toFloat() 59 | paint.strokeCap = Paint.Cap.ROUND 60 | paint.color = needleColor 61 | } 62 | 63 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 64 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 65 | 66 | val calWidth = 2 * needleJointRadius 67 | val calHeight = (2 * needleJointRadius) + needleLength 68 | setMeasuredDimension(calWidth, calHeight) 69 | } 70 | 71 | 72 | override fun onDraw(canvas: Canvas) { 73 | super.onDraw(canvas) 74 | 75 | //joint circle 76 | canvas.drawCircle(needleJointRadius.toFloat(), (needleJointRadius + needleLength).toFloat(), needleJointRadius.toFloat(), paint) 77 | 78 | //needle line 79 | canvas.drawLine(needleJointRadius.toFloat(), (needleWidth / 2).toFloat(), needleJointRadius.toFloat(), needleLength.toFloat(), paint) 80 | } 81 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/contracts/CircularSticksAbstractView.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.contracts 2 | 3 | import android.content.Context 4 | import android.graphics.Canvas 5 | import android.graphics.Paint 6 | import android.graphics.RectF 7 | import android.util.AttributeSet 8 | import android.view.View 9 | 10 | abstract class CircularSticksAbstractView : View, LoaderContract { 11 | 12 | var noOfSticks: Int = 80 13 | 14 | var outerCircleRadius: Float = 200.0f 15 | var innerCircleRadius: Float = 100.0f 16 | 17 | open var sticksColor: Int = resources.getColor(android.R.color.darker_gray) 18 | var viewBackgroundColor: Int = resources.getColor(android.R.color.white) 19 | 20 | protected lateinit var sticksPaint: Paint 21 | protected lateinit var innerCirclePaint: Paint 22 | 23 | protected lateinit var outerCircleOval: RectF 24 | 25 | constructor(context: Context) : super(context) 26 | 27 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) 28 | 29 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) 30 | 31 | open fun initPaints() { 32 | sticksPaint = Paint() 33 | sticksPaint.color = sticksColor 34 | sticksPaint.style = Paint.Style.FILL 35 | sticksPaint.isAntiAlias = true 36 | 37 | outerCircleOval = RectF().apply { 38 | left = 0f 39 | top = 0f 40 | right = 2 * outerCircleRadius 41 | bottom = 2 * outerCircleRadius 42 | } 43 | 44 | innerCirclePaint = Paint() 45 | innerCirclePaint.color = viewBackgroundColor 46 | innerCirclePaint.style = Paint.Style.FILL 47 | innerCirclePaint.isAntiAlias = true 48 | } 49 | 50 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 51 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 52 | setMeasuredDimension(2 * outerCircleRadius.toInt(), 2 * outerCircleRadius.toInt()) 53 | } 54 | 55 | override fun onDraw(canvas: Canvas) { 56 | super.onDraw(canvas) 57 | 58 | if (noOfSticks < 1) { 59 | noOfSticks = 8 60 | } 61 | 62 | val sweepAngle: Float = (360f / (2 * noOfSticks)) 63 | var startAngle: Float = (0 - (sweepAngle / 2)) 64 | 65 | for (i in 0 until noOfSticks) { 66 | canvas.drawArc(outerCircleOval, startAngle, sweepAngle, true, sticksPaint) 67 | startAngle += (2 * sweepAngle) 68 | } 69 | 70 | canvas.drawCircle(outerCircleRadius, outerCircleRadius, innerCircleRadius, innerCirclePaint) 71 | } 72 | 73 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/contracts/LoaderContract.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.contracts 2 | 3 | import android.util.AttributeSet 4 | 5 | /** 6 | * Created by suneet on 10/29/17. 7 | */ 8 | interface LoaderContract { 9 | fun initAttributes(attrs: AttributeSet) 10 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/contracts/RippleAbstractView.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.contracts 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.animation.* 6 | import android.widget.LinearLayout 7 | 8 | abstract class RippleAbstractView : LinearLayout, LoaderContract { 9 | 10 | var circleInitialRadius: Int = 40 11 | 12 | var circleColor: Int = resources.getColor(android.R.color.holo_red_dark) 13 | 14 | var fromAlpha: Float = 0.9f 15 | 16 | var toAlpha: Float = 0.01f 17 | 18 | var animationDuration = 2000 19 | 20 | var interpolator: Interpolator = DecelerateInterpolator() 21 | 22 | constructor(context: Context) : super(context) 23 | 24 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) 25 | 26 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) 27 | 28 | abstract fun initView() 29 | 30 | abstract fun startLoading() 31 | 32 | protected fun getAnimSet(): Animation { 33 | val set = AnimationSet(true) 34 | 35 | val scaleAnim = ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f, 36 | Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f) 37 | scaleAnim.duration = animationDuration.toLong() 38 | scaleAnim.repeatCount = Animation.INFINITE 39 | 40 | 41 | val alphaAnim = AlphaAnimation(fromAlpha, toAlpha) 42 | alphaAnim.duration = animationDuration.toLong() 43 | alphaAnim.repeatCount = Animation.INFINITE 44 | 45 | set.addAnimation(scaleAnim) 46 | set.addAnimation(alphaAnim) 47 | 48 | set.duration = animationDuration.toLong() 49 | set.interpolator = interpolator 50 | set.repeatCount = Animation.INFINITE 51 | set.repeatMode = Animation.RESTART 52 | 53 | return set 54 | } 55 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/ArcProgressLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.content.Context 4 | import android.graphics.Canvas 5 | import android.graphics.Paint 6 | import android.graphics.RectF 7 | import android.util.AttributeSet 8 | import android.view.View 9 | import com.agrawalsuneet.loaderspack.R 10 | import com.agrawalsuneet.loaderspack.contracts.LoaderContract 11 | 12 | /** 13 | * Created by agrawalsuneet on 9/16/18. 14 | */ 15 | 16 | class ArcProgressLoader : View, LoaderContract { 17 | 18 | var arcRadius: Int = 200 19 | var arcWidth: Int = 40 20 | 21 | var incrementalAngle: Float = 6.0f 22 | 23 | var maxArcAngle: Float = 200.0f 24 | set(value) { 25 | field = if (value > 360) (value % 360) else value 26 | } 27 | 28 | var arcColorsArray: IntArray = intArrayOf(resources.getColor(android.R.color.holo_red_dark), 29 | resources.getColor(android.R.color.holo_orange_light), 30 | resources.getColor(android.R.color.holo_green_light)) 31 | 32 | private val paint: Paint = Paint() 33 | private var centerPoint: Float = 0.0f 34 | private var acrRect = RectF() 35 | 36 | private val ZeroAngle: Float = 270.0f 37 | private val ThreeSixtyAngle: Float = 630.0f 38 | 39 | private var startAngle: Float = ZeroAngle 40 | private var endAngle: Float = ZeroAngle + incrementalAngle 41 | private var colorIndex: Int = 0 42 | 43 | 44 | constructor(context: Context) : super(context) { 45 | initValues() 46 | } 47 | 48 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 49 | initAttributes(attrs) 50 | initValues() 51 | } 52 | 53 | constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) { 54 | initAttributes(attrs) 55 | initValues() 56 | } 57 | 58 | constructor(context: Context, arcRadius: Int, arcWidth: Int, incrementalAngle: Float, maxArcAngle: Float, arcColorsArray: IntArray) : super(context) { 59 | this.arcRadius = arcRadius 60 | this.arcWidth = arcWidth 61 | this.incrementalAngle = incrementalAngle 62 | this.maxArcAngle = maxArcAngle 63 | this.arcColorsArray = arcColorsArray 64 | initValues() 65 | } 66 | 67 | override fun initAttributes(attrs: AttributeSet) { 68 | 69 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ArcProgressLoader) 70 | 71 | arcRadius = typedArray.getDimensionPixelSize(R.styleable.ArcProgressLoader_arcprogress_arcRadius, 200) 72 | 73 | arcWidth = typedArray.getDimensionPixelSize(R.styleable.ArcProgressLoader_arcprogress_arcWidth, 40) 74 | 75 | incrementalAngle = typedArray.getFloat(R.styleable.ArcProgressLoader_arcprogress_incrementalAngle, 6.0f) 76 | 77 | maxArcAngle = typedArray.getFloat(R.styleable.ArcProgressLoader_arcprogress_maxArcAngle, 200.0f) 78 | 79 | val colorsArrayId = typedArray.getResourceId(R.styleable.ArcProgressLoader_arcprogress_arcColorsArray, 0) 80 | 81 | typedArray.recycle() 82 | 83 | if (colorsArrayId != 0) { 84 | arcColorsArray = resources.getIntArray(colorsArrayId) 85 | 86 | if (arcColorsArray.isEmpty()) { 87 | throw RuntimeException("ArcProgressLoader : Please provide a valid, non-empty colors array") 88 | } 89 | } 90 | } 91 | 92 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 93 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 94 | 95 | val widthHeight = (2 * (arcRadius)) + arcWidth 96 | setMeasuredDimension(widthHeight, widthHeight) 97 | } 98 | 99 | private fun initValues() { 100 | centerPoint = (arcRadius + (arcWidth / 2)).toFloat() 101 | 102 | acrRect = RectF().apply { 103 | left = centerPoint - arcRadius 104 | right = centerPoint + arcRadius 105 | top = centerPoint - arcRadius 106 | bottom = centerPoint + arcRadius 107 | } 108 | 109 | paint.isAntiAlias = true 110 | 111 | paint.style = Paint.Style.STROKE 112 | paint.strokeWidth = arcWidth.toFloat() 113 | paint.strokeCap = Paint.Cap.ROUND 114 | } 115 | 116 | 117 | override fun onDraw(canvas: Canvas) { 118 | super.onDraw(canvas) 119 | 120 | 121 | val sweepAngle = endAngle - startAngle 122 | 123 | paint.color = arcColorsArray[colorIndex] 124 | canvas.drawArc(acrRect, startAngle, sweepAngle, false, paint) 125 | 126 | 127 | //both reached the end, restart with next color 128 | if (startAngle >= ThreeSixtyAngle && endAngle >= ThreeSixtyAngle) { 129 | startAngle = ZeroAngle 130 | endAngle = ZeroAngle + incrementalAngle 131 | 132 | 133 | if (colorIndex == arcColorsArray.lastIndex) { 134 | colorIndex = 0 135 | } else { 136 | colorIndex++ 137 | } 138 | paint.color = arcColorsArray[colorIndex] 139 | 140 | } 141 | 142 | //endangle didn't reach end, keep increasing 143 | else if (endAngle < ThreeSixtyAngle) { 144 | 145 | endAngle += incrementalAngle 146 | 147 | //max arc angel reached increase start angel also 148 | if (sweepAngle >= maxArcAngle) { 149 | startAngle += incrementalAngle 150 | } 151 | } 152 | 153 | //end angel reached limit, increase only start angel 154 | else { 155 | startAngle += incrementalAngle 156 | } 157 | 158 | postInvalidate() 159 | } 160 | 161 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/CircularSticksLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | import android.graphics.Canvas 6 | import android.graphics.Paint 7 | import android.util.AttributeSet 8 | import android.view.View 9 | import com.agrawalsuneet.dotsloader.utils.Helper 10 | import com.agrawalsuneet.loaderspack.R 11 | import com.agrawalsuneet.loaderspack.contracts.CircularSticksAbstractView 12 | import com.agrawalsuneet.loaderspack.utils.Utils 13 | import java.util.* 14 | 15 | /** 16 | * Created by suneet on 1/5/18. 17 | */ 18 | class CircularSticksLoader : CircularSticksAbstractView { 19 | 20 | override var sticksColor: Int = resources.getColor(android.R.color.darker_gray) 21 | set(defaultColor) { 22 | field = defaultColor 23 | if (defaultStickPaint != null) { 24 | defaultStickPaint?.color = defaultColor 25 | } 26 | } 27 | 28 | var selectedStickColor: Int = resources.getColor(android.R.color.black) 29 | set(selectedColor) { 30 | field = selectedColor 31 | if (selectedStickPaint != null) { 32 | selectedStickPaint?.color = selectedColor 33 | initShadowPaints() 34 | } 35 | } 36 | 37 | var showRunningShadow: Boolean = true 38 | 39 | var firstShadowColor: Int = 0 40 | set(value) { 41 | if (value != 0) { 42 | field = value 43 | isShadowColorSet = true 44 | if (firstShadowPaint != null) { 45 | firstShadowPaint?.color = value 46 | } 47 | } 48 | } 49 | 50 | 51 | var secondShadowColor: Int = 0 52 | set(value) { 53 | if (value != 0) { 54 | field = value 55 | isShadowColorSet = true 56 | if (secondShadowPaint != null) { 57 | secondShadowPaint?.color = value 58 | } 59 | } 60 | } 61 | 62 | var animDuration = 100 63 | 64 | private var isShadowColorSet = false 65 | 66 | private var selectedStickPos = 1 67 | private var shouldAnimate = true 68 | 69 | private var defaultStickPaint: Paint? = null 70 | private var selectedStickPaint: Paint? = null 71 | 72 | private var firstShadowPaint: Paint? = null 73 | private var secondShadowPaint: Paint? = null 74 | 75 | private var timer: Timer? = null 76 | 77 | var isAnimating: Boolean = false 78 | private set 79 | 80 | constructor(context: Context) : super(context) { 81 | initPaints() 82 | } 83 | 84 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 85 | initAttributes(attrs) 86 | initPaints() 87 | initShadowPaints() 88 | } 89 | 90 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 91 | initAttributes(attrs) 92 | initPaints() 93 | initShadowPaints() 94 | } 95 | 96 | constructor(context: Context, noOfSticks: Int, outerCircleRadius: Float, innerCircleRadius: Float, 97 | sticksColor: Int, selectedStickColor: Int, viewBackgroundColor: Int) : super(context) { 98 | this.noOfSticks = noOfSticks 99 | this.outerCircleRadius = outerCircleRadius 100 | this.innerCircleRadius = innerCircleRadius 101 | this.sticksColor = sticksColor 102 | this.selectedStickColor = selectedStickColor 103 | this.viewBackgroundColor = viewBackgroundColor 104 | initPaints() 105 | initShadowPaints() 106 | } 107 | 108 | override fun initAttributes(attrs: AttributeSet) { 109 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularSticksLoader, 0, 0) 110 | 111 | this.noOfSticks = typedArray 112 | .getInteger(R.styleable.CircularSticksLoader_circularsticks_noOfSticks, 80) 113 | 114 | this.outerCircleRadius = typedArray 115 | .getDimension(R.styleable.CircularSticksLoader_circularsticks_outerCircleRadius, 200.0f) 116 | this.innerCircleRadius = typedArray 117 | .getDimension(R.styleable.CircularSticksLoader_circularsticks_innerCircleRadius, 100.0f) 118 | 119 | 120 | this.sticksColor = typedArray 121 | .getColor(R.styleable.CircularSticksLoader_circularsticks_stickColor, resources.getColor(android.R.color.darker_gray)) 122 | this.selectedStickColor = typedArray 123 | .getColor(R.styleable.CircularSticksLoader_circularsticks_selectedStickColor, resources.getColor(android.R.color.black)) 124 | 125 | this.viewBackgroundColor = typedArray 126 | .getColor(R.styleable.CircularSticksLoader_circularsticks_viewBackgroundColor, resources.getColor(android.R.color.white)) 127 | 128 | this.showRunningShadow = typedArray.getBoolean(R.styleable.CircularSticksLoader_circularsticks_showRunningShadow, true) 129 | 130 | this.firstShadowColor = typedArray.getColor(R.styleable.CircularSticksLoader_circularsticks_firstShadowColor, 0) 131 | this.secondShadowColor = typedArray.getColor(R.styleable.CircularSticksLoader_circularsticks_secondShadowColor, 0) 132 | 133 | animDuration = typedArray.getInteger(R.styleable.CircularSticksLoader_circularsticks_animDuration, 100) 134 | 135 | typedArray.recycle() 136 | } 137 | 138 | override fun onVisibilityChanged(changedView: View, visibility: Int) { 139 | super.onVisibilityChanged(changedView, visibility) 140 | 141 | if (visibility != VISIBLE) { 142 | timer?.cancel() 143 | isAnimating = false 144 | } else if (shouldAnimate) { 145 | scheduleTimer() 146 | } 147 | } 148 | 149 | override fun onDraw(canvas: Canvas) { 150 | super.onDraw(canvas) 151 | 152 | drawCircle(canvas) 153 | } 154 | 155 | private fun drawCircle(canvas: Canvas) { 156 | val firstShadowPos = if (selectedStickPos == 1) noOfSticks else selectedStickPos - 1 157 | val secondShadowPos = if (firstShadowPos == 1) noOfSticks else firstShadowPos - 1 158 | 159 | val sweepAngle: Float = (360f / (2 * noOfSticks)) 160 | var startAngle: Float = (0 - (sweepAngle / 2)) 161 | 162 | for (i in 0 until noOfSticks) { 163 | 164 | if (i + 1 == selectedStickPos) { 165 | canvas.drawArc(outerCircleOval, startAngle, sweepAngle, true, selectedStickPaint!!) 166 | } else if (this.showRunningShadow && i + 1 == firstShadowPos) { 167 | canvas.drawArc(outerCircleOval, startAngle, sweepAngle, true, firstShadowPaint!!) 168 | } else if (this.showRunningShadow && i + 1 == secondShadowPos) { 169 | canvas.drawArc(outerCircleOval, startAngle, sweepAngle, true, secondShadowPaint!!) 170 | } else { 171 | canvas.drawArc(outerCircleOval, startAngle, sweepAngle, true, sticksPaint) 172 | } 173 | 174 | startAngle += (2 * sweepAngle) 175 | 176 | } 177 | 178 | canvas.drawCircle(outerCircleRadius, outerCircleRadius, innerCircleRadius, innerCirclePaint) 179 | } 180 | 181 | override fun initPaints() { 182 | super.initPaints() 183 | 184 | selectedStickPaint = Paint() 185 | selectedStickPaint?.color = selectedStickColor 186 | selectedStickPaint?.style = Paint.Style.FILL 187 | selectedStickPaint?.isAntiAlias = true 188 | } 189 | 190 | private fun initShadowPaints() { 191 | if (showRunningShadow) { 192 | if (!isShadowColorSet) { 193 | firstShadowColor = Helper.adjustAlpha(selectedStickColor, 0.7f) 194 | secondShadowColor = Helper.adjustAlpha(selectedStickColor, 0.5f) 195 | isShadowColorSet = true 196 | } 197 | 198 | firstShadowPaint = Paint() 199 | firstShadowPaint?.isAntiAlias = true 200 | firstShadowPaint?.style = Paint.Style.FILL 201 | firstShadowPaint?.color = firstShadowColor 202 | 203 | secondShadowPaint = Paint() 204 | secondShadowPaint?.isAntiAlias = true 205 | secondShadowPaint?.style = Paint.Style.FILL 206 | secondShadowPaint?.color = secondShadowColor 207 | } 208 | } 209 | 210 | fun startAnimation() { 211 | shouldAnimate = true 212 | scheduleTimer() 213 | } 214 | 215 | fun stopAnimation() { 216 | shouldAnimate = false 217 | timer?.cancel() 218 | isAnimating = false 219 | } 220 | 221 | private fun scheduleTimer() { 222 | timer = Timer() 223 | timer?.scheduleAtFixedRate(object : TimerTask() { 224 | override fun run() { 225 | selectedStickPos++ 226 | 227 | if (selectedStickPos > noOfSticks) { 228 | selectedStickPos = 1 229 | } 230 | 231 | (Utils.scanForActivity(context))?.runOnUiThread { invalidate() } 232 | } 233 | }, 0, animDuration.toLong()) 234 | 235 | isAnimating = true 236 | } 237 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/ClockLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.content.Context 4 | import android.graphics.Canvas 5 | import android.graphics.Paint 6 | import android.graphics.RectF 7 | import android.util.AttributeSet 8 | import android.view.View 9 | import com.agrawalsuneet.loaderspack.R 10 | import com.agrawalsuneet.loaderspack.contracts.LoaderContract 11 | 12 | 13 | /** 14 | * Created by suneet on 10/29/17. 15 | */ 16 | 17 | class ClockLoader : View, LoaderContract { 18 | 19 | var outerCircleBorderWidth: Float = 30.0f 20 | set(value) { 21 | field = value 22 | initPaints() 23 | initValues() 24 | } 25 | 26 | var bigCircleRadius: Float = 350.0f 27 | set(value) { 28 | field = value 29 | initValues() 30 | } 31 | 32 | var innerCircleRadius: Float = 20.0f 33 | set(value) { 34 | field = value 35 | initValues() 36 | } 37 | 38 | var hourHandLength: Float = 240.0f 39 | set(value) { 40 | field = value 41 | initValues() 42 | } 43 | var minuteHandLength: Float = 300.0f 44 | set(value) { 45 | field = value 46 | initValues() 47 | } 48 | 49 | var outerCircleBorderColor: Int = resources.getColor(android.R.color.darker_gray) 50 | set(value) { 51 | field = value 52 | initPaints() 53 | } 54 | 55 | var bigCircleColor: Int = resources.getColor(android.R.color.black) 56 | set(value) { 57 | field = value 58 | initPaints() 59 | } 60 | 61 | var hourHandColor: Int = resources.getColor(android.R.color.darker_gray) 62 | set(value) { 63 | field = value 64 | initPaints() 65 | } 66 | 67 | var minuteHandColor: Int = resources.getColor(android.R.color.darker_gray) 68 | set(value) { 69 | field = value 70 | initPaints() 71 | } 72 | 73 | var innerCircleColor: Int = resources.getColor(android.R.color.darker_gray) 74 | set(value) { 75 | field = value 76 | initPaints() 77 | } 78 | 79 | var animSpeedMultiplier: Float = 1.0f 80 | 81 | private var minuteHandAngle: Float = 267.0f 82 | private var hourHandAngle: Float = 327.0f 83 | 84 | private var centerPoint: Float = 0.0f 85 | 86 | private lateinit var hourOval: RectF 87 | private lateinit var minuteOval: RectF 88 | 89 | private lateinit var borderPaint: Paint 90 | private lateinit var bigCirclePaint: Paint 91 | private lateinit var innerCirclePaint: Paint 92 | private lateinit var minuteHandPaint: Paint 93 | private lateinit var hourHandPaint: Paint 94 | 95 | constructor(context: Context) : super(context) { 96 | initPaints() 97 | initValues() 98 | } 99 | 100 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 101 | initAttributes(attrs) 102 | initPaints() 103 | initValues() 104 | } 105 | 106 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 107 | initAttributes(attrs) 108 | initPaints() 109 | initValues() 110 | } 111 | 112 | override fun initAttributes(attrs: AttributeSet) { 113 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ClockLoader, 0, 0) 114 | 115 | this.outerCircleBorderWidth = typedArray 116 | .getDimension(R.styleable.ClockLoader_clock_outerCircleBorderWidth, 30.0f) 117 | this.bigCircleRadius = typedArray 118 | .getDimension(R.styleable.ClockLoader_clock_bigCircleRadius, 350.0f) 119 | this.innerCircleRadius = typedArray 120 | .getDimension(R.styleable.ClockLoader_clock_innerCircleRadius, 20.0f) 121 | this.hourHandLength = typedArray 122 | .getDimension(R.styleable.ClockLoader_clock_hourHandLength, 240.0f) 123 | this.minuteHandLength = typedArray 124 | .getDimension(R.styleable.ClockLoader_clock_minuteHandLength, 300.0f) 125 | 126 | this.outerCircleBorderColor = typedArray 127 | .getColor(R.styleable.ClockLoader_clock_outerCircleBorderColor, resources.getColor(android.R.color.darker_gray)) 128 | this.bigCircleColor = typedArray 129 | .getColor(R.styleable.ClockLoader_clock_bigCircleColor, resources.getColor(android.R.color.black)) 130 | this.innerCircleColor = typedArray 131 | .getColor(R.styleable.ClockLoader_clock_innerCircleColor, resources.getColor(android.R.color.darker_gray)) 132 | this.hourHandColor = typedArray 133 | .getColor(R.styleable.ClockLoader_clock_hourHandColor, resources.getColor(android.R.color.darker_gray)) 134 | this.minuteHandColor = typedArray 135 | .getColor(R.styleable.ClockLoader_clock_minuteHandColor, resources.getColor(android.R.color.darker_gray)) 136 | 137 | this.animSpeedMultiplier = typedArray 138 | .getFloat(R.styleable.ClockLoader_clock_animSpeedMultiplier, 1.0f) 139 | 140 | typedArray.recycle() 141 | } 142 | 143 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 144 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 145 | 146 | setMeasuredDimension(2 * (bigCircleRadius + outerCircleBorderWidth).toInt(), 147 | 2 * (bigCircleRadius + outerCircleBorderWidth).toInt()) 148 | } 149 | 150 | 151 | private fun initPaints() { 152 | borderPaint = Paint() 153 | borderPaint.color = outerCircleBorderColor 154 | borderPaint.style = Paint.Style.STROKE 155 | borderPaint.isAntiAlias = true 156 | borderPaint.strokeWidth = outerCircleBorderWidth 157 | 158 | bigCirclePaint = Paint() 159 | bigCirclePaint.color = bigCircleColor 160 | bigCirclePaint.style = Paint.Style.FILL 161 | bigCirclePaint.isAntiAlias = true 162 | 163 | innerCirclePaint = Paint() 164 | innerCirclePaint.color = innerCircleColor 165 | innerCirclePaint.style = Paint.Style.FILL 166 | innerCirclePaint.isAntiAlias = true 167 | 168 | hourHandPaint = Paint() 169 | hourHandPaint.color = hourHandColor 170 | hourHandPaint.style = Paint.Style.FILL 171 | hourHandPaint.isAntiAlias = true 172 | 173 | minuteHandPaint = Paint() 174 | minuteHandPaint.color = minuteHandColor 175 | minuteHandPaint.style = Paint.Style.FILL 176 | minuteHandPaint.isAntiAlias = true 177 | } 178 | 179 | private fun initValues() { 180 | centerPoint = bigCircleRadius + outerCircleBorderWidth 181 | 182 | hourOval = RectF().apply { 183 | left = centerPoint - hourHandLength 184 | right = centerPoint + hourHandLength 185 | top = centerPoint - hourHandLength 186 | bottom = centerPoint + hourHandLength 187 | } 188 | 189 | minuteOval = RectF().apply { 190 | left = centerPoint - minuteHandLength 191 | right = centerPoint + minuteHandLength 192 | top = centerPoint - minuteHandLength 193 | bottom = centerPoint + minuteHandLength 194 | } 195 | } 196 | 197 | override fun onDraw(canvas: Canvas) { 198 | super.onDraw(canvas) 199 | 200 | canvas.drawCircle(centerPoint, 201 | centerPoint, 202 | bigCircleRadius, bigCirclePaint) 203 | 204 | canvas.drawCircle(centerPoint, 205 | centerPoint, 206 | bigCircleRadius, borderPaint) 207 | 208 | canvas.drawArc(hourOval, hourHandAngle, 6.0f, true, hourHandPaint) 209 | 210 | canvas.drawArc(minuteOval, minuteHandAngle, 6.0f, true, minuteHandPaint) 211 | 212 | canvas.drawCircle(centerPoint, 213 | centerPoint, 214 | innerCircleRadius, innerCirclePaint) 215 | 216 | minuteHandAngle += (6.0f * animSpeedMultiplier) 217 | hourHandAngle += (0.5f * animSpeedMultiplier) 218 | 219 | if (minuteHandAngle > 360.0f) { 220 | minuteHandAngle -= 360.0f 221 | } 222 | 223 | if (hourHandAngle > 360.0f) { 224 | hourHandAngle -= 360.0f 225 | } 226 | 227 | postInvalidateOnAnimation() 228 | } 229 | 230 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/CurvesLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.Gravity 6 | import android.view.View 7 | import android.view.ViewTreeObserver 8 | import android.view.animation.* 9 | import android.widget.LinearLayout 10 | import android.widget.RelativeLayout 11 | import com.agrawalsuneet.dotsloader.utils.random 12 | import com.agrawalsuneet.loaderspack.R 13 | import com.agrawalsuneet.loaderspack.basicviews.ArcView 14 | import com.agrawalsuneet.loaderspack.contracts.LoaderContract 15 | import java.util.* 16 | 17 | /** 18 | * Created by agrawalsuneet on 9/4/18. 19 | */ 20 | 21 | class CurvesLoader : LinearLayout, LoaderContract { 22 | 23 | var noOfCurves: Int = 4 24 | 25 | var outermostCurveRadius: Int = 100 26 | var curveWidth: Int = 10 27 | var distanceBetweenCurves: Int = 10 28 | var curveSweepAngle: Float = 160.0f 29 | 30 | var curveColor: Int = resources.getColor(android.R.color.holo_red_light) 31 | 32 | var animDuration: Int = 1500 33 | 34 | var interpolator: Interpolator = LinearInterpolator() 35 | 36 | private lateinit var relativeLayout: RelativeLayout 37 | 38 | private var calWidthHeight: Int = 0 39 | private val curvesArray: ArrayList = arrayListOf() 40 | 41 | 42 | constructor(context: Context) : super(context) { 43 | initView() 44 | } 45 | 46 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 47 | initAttributes(attrs) 48 | initView() 49 | } 50 | 51 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 52 | initAttributes(attrs) 53 | initView() 54 | } 55 | 56 | constructor(context: Context, noOfCurves: Int, outermostCurveRadius: Int, curveWidth: Int, distanceBetweenCurves: Int, curveSweepAngle: Float, curveColor: Int) : super(context) { 57 | this.noOfCurves = noOfCurves 58 | this.outermostCurveRadius = outermostCurveRadius 59 | this.curveWidth = curveWidth 60 | this.distanceBetweenCurves = distanceBetweenCurves 61 | this.curveSweepAngle = curveSweepAngle 62 | this.curveColor = curveColor 63 | initView() 64 | } 65 | 66 | 67 | override fun initAttributes(attrs: AttributeSet) { 68 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CurvesLoader, 0, 0) 69 | 70 | this.noOfCurves = typedArray.getInteger(R.styleable.CurvesLoader_curves_noOfCurves, 4) 71 | 72 | this.outermostCurveRadius = typedArray.getDimensionPixelSize(R.styleable.CurvesLoader_curves_outermostCurveRadius, 100) 73 | 74 | this.curveWidth = typedArray.getDimensionPixelSize(R.styleable.CurvesLoader_curves_curveWidth, 10) 75 | this.distanceBetweenCurves = typedArray.getDimensionPixelSize(R.styleable.CurvesLoader_curves_distanceBetweenCurves, 10) 76 | 77 | this.curveSweepAngle = typedArray.getFloat(R.styleable.CurvesLoader_curves_curveSweepAngle, 160.0f) 78 | 79 | this.curveColor = typedArray.getColor(R.styleable.CurvesLoader_curves_curveColor, 80 | resources.getColor(android.R.color.holo_red_light)) 81 | 82 | this.animDuration = typedArray.getInt(R.styleable.CurvesLoader_curves_animDuration, 1500) 83 | 84 | this.interpolator = AnimationUtils.loadInterpolator(context, 85 | typedArray.getResourceId(R.styleable.CurvesLoader_curves_interpolator, 86 | android.R.anim.linear_interpolator)) 87 | 88 | typedArray.recycle() 89 | } 90 | 91 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 92 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 93 | 94 | if (calWidthHeight == 0) { 95 | calWidthHeight = (2 * outermostCurveRadius) + curveWidth 96 | } 97 | 98 | setMeasuredDimension(calWidthHeight, calWidthHeight) 99 | } 100 | 101 | private fun initView() { 102 | removeAllViews() 103 | removeAllViewsInLayout() 104 | 105 | this.gravity = Gravity.CENTER_HORIZONTAL 106 | 107 | relativeLayout = RelativeLayout(context) 108 | relativeLayout.gravity = Gravity.CENTER_HORIZONTAL 109 | 110 | if (calWidthHeight == 0) { 111 | calWidthHeight = (2 * outermostCurveRadius) + curveWidth 112 | } 113 | 114 | 115 | var startAngle = 0.0f 116 | 117 | 118 | for (i in 0 until noOfCurves) { 119 | 120 | val circleRadius = outermostCurveRadius - (i * curveWidth) - (i * distanceBetweenCurves) 121 | 122 | val arcView = ArcView(context, circleRadius, curveWidth, startAngle, curveSweepAngle, curveColor, true) 123 | startAngle += (10..80).random() 124 | 125 | 126 | val widthHeight = (2 * circleRadius) + curveWidth 127 | val param = RelativeLayout.LayoutParams(widthHeight, widthHeight) 128 | param.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE) 129 | 130 | relativeLayout.addView(arcView, param) 131 | 132 | 133 | curvesArray.add(arcView) 134 | } 135 | 136 | val relParam = LinearLayout.LayoutParams(calWidthHeight, calWidthHeight) 137 | this.addView(relativeLayout, relParam) 138 | 139 | 140 | viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { 141 | override fun onGlobalLayout() { 142 | startLoading() 143 | 144 | this@CurvesLoader.viewTreeObserver.removeOnGlobalLayoutListener(this) 145 | } 146 | }) 147 | } 148 | 149 | override fun onVisibilityChanged(changedView: View, visibility: Int) { 150 | super.onVisibilityChanged(changedView, visibility) 151 | 152 | if (visibility == View.VISIBLE) { 153 | initView() 154 | } else { 155 | for (curve in curvesArray) { 156 | curve.clearAnimation() 157 | } 158 | } 159 | } 160 | 161 | private fun startLoading() { 162 | 163 | for (i in 0..curvesArray.lastIndex) { 164 | val arcView = curvesArray[i] 165 | val anim = getRotateAnim(i, arcView) 166 | arcView.startAnimation(anim) 167 | } 168 | } 169 | 170 | private fun getRotateAnim(circleCount: Int, arcView: ArcView): RotateAnimation { 171 | 172 | val fromDegree = if (circleCount == curvesArray.lastIndex) 360.0f else 0.0f 173 | val toDegree = if (circleCount == curvesArray.lastIndex) 0.0f else 360.0f 174 | 175 | val rotateAnimation = RotateAnimation(fromDegree, toDegree, 176 | (arcView.width / 2).toFloat(), (arcView.height / 2).toFloat()) 177 | rotateAnimation.duration = animDuration.toLong() 178 | rotateAnimation.fillAfter = true 179 | rotateAnimation.interpolator = interpolator 180 | rotateAnimation.repeatCount = Animation.INFINITE 181 | 182 | return rotateAnimation 183 | } 184 | 185 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/FidgetLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.Gravity 6 | import android.view.ViewTreeObserver 7 | import android.view.animation.* 8 | import android.widget.LinearLayout 9 | import com.agrawalsuneet.loaderspack.R 10 | import com.agrawalsuneet.loaderspack.basicviews.FidgetView 11 | import com.agrawalsuneet.loaderspack.contracts.LoaderContract 12 | 13 | /** 14 | * Created by agrawalsuneet on 9/20/18. 15 | */ 16 | class FidgetLoader : LinearLayout, LoaderContract { 17 | 18 | var fidgetRadius: Int = 100 19 | var bodyColor: Int = resources.getColor(android.R.color.holo_red_light) 20 | var sideCirclesColor = resources.getColor(android.R.color.darker_gray) 21 | 22 | var noOfRotation: Int = 20 23 | var animDuration: Int = 3000 24 | var interpolator: Interpolator = AccelerateDecelerateInterpolator() 25 | 26 | private lateinit var fidgetView: FidgetView 27 | 28 | constructor(context: Context) : super(context) { 29 | initView() 30 | } 31 | 32 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 33 | initAttributes(attrs) 34 | initView() 35 | } 36 | 37 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 38 | initAttributes(attrs) 39 | initView() 40 | } 41 | 42 | constructor(context: Context, fidgetRadius: Int, bodyColor: Int, sideCirclesColor: Int) : super(context) { 43 | this.fidgetRadius = fidgetRadius 44 | this.bodyColor = bodyColor 45 | this.sideCirclesColor = sideCirclesColor 46 | initView() 47 | } 48 | 49 | 50 | override fun initAttributes(attrs: AttributeSet) { 51 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.FidgetLoader, 0, 0) 52 | 53 | fidgetRadius = typedArray.getDimensionPixelSize(R.styleable.FidgetLoader_fidget_fidgetRadius, 100) 54 | 55 | bodyColor = typedArray.getColor(R.styleable.FidgetLoader_fidget_bodyColor, 56 | resources.getColor(android.R.color.holo_red_light)) 57 | 58 | sideCirclesColor = typedArray.getColor(R.styleable.FidgetLoader_fidget_sideCirclesColor, 59 | resources.getColor(android.R.color.darker_gray)) 60 | 61 | 62 | noOfRotation = typedArray.getInt(R.styleable.FidgetLoader_fidget_noOfRotation, 20) 63 | 64 | animDuration = typedArray.getInt(R.styleable.FidgetLoader_fidget_animDuration, 3000) 65 | 66 | interpolator = AnimationUtils.loadInterpolator(context, 67 | typedArray.getResourceId(R.styleable.FidgetLoader_fidget_interpolator, 68 | android.R.anim.accelerate_decelerate_interpolator)) 69 | 70 | typedArray.recycle() 71 | } 72 | 73 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 74 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 75 | 76 | val calWidthHeight = (2 * fidgetRadius) + (4 * FidgetView.distanceFactor * (fidgetRadius)).toFloat() 77 | setMeasuredDimension(calWidthHeight.toInt(), calWidthHeight.toInt()) 78 | } 79 | 80 | private fun initView() { 81 | removeAllViews() 82 | removeAllViewsInLayout() 83 | 84 | this.gravity = Gravity.CENTER 85 | this.orientation = LinearLayout.VERTICAL 86 | 87 | fidgetView = FidgetView(context, fidgetRadius, bodyColor, sideCirclesColor) 88 | this.addView(fidgetView) 89 | 90 | val loaderView = this 91 | 92 | viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { 93 | override fun onGlobalLayout() { 94 | startLoading() 95 | 96 | val vto = loaderView.viewTreeObserver 97 | vto.removeOnGlobalLayoutListener(this) 98 | } 99 | }) 100 | } 101 | 102 | private fun startLoading() { 103 | val anim = getRotateAnim() 104 | fidgetView.startAnimation(anim) 105 | } 106 | 107 | private fun getRotateAnim(): RotateAnimation { 108 | 109 | val fromDegree = 0.0f 110 | val toDegree = 360f * noOfRotation 111 | 112 | val rotateAnimation = RotateAnimation(fromDegree, toDegree, 113 | fidgetView.pivotX, fidgetView.pivotY) 114 | rotateAnimation.duration = animDuration.toLong() 115 | rotateAnimation.fillAfter = true 116 | rotateAnimation.interpolator = interpolator 117 | rotateAnimation.repeatCount = Animation.INFINITE 118 | 119 | return rotateAnimation 120 | } 121 | 122 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/GaugeLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.ViewGroup 6 | import android.view.ViewTreeObserver 7 | import android.view.animation.* 8 | import android.widget.RelativeLayout 9 | import com.agrawalsuneet.dotsloader.utils.random 10 | import com.agrawalsuneet.loaderspack.R 11 | import com.agrawalsuneet.loaderspack.basicviews.ArcView 12 | import com.agrawalsuneet.loaderspack.contracts.LoaderContract 13 | import com.agrawalsuneet.loaderspack.basicviews.NeedleView 14 | 15 | class GaugeLoader : RelativeLayout, LoaderContract { 16 | 17 | var rangeIndicatorRadius: Int = 140 18 | var rangeIndicatorWidth: Int = 100 19 | var needleWidth: Int = 20 20 | var needleJointRadius: Int = 45 21 | 22 | var lowerRangeColor: Int = resources.getColor(android.R.color.holo_green_light) 23 | var higherRangeColor: Int = resources.getColor(android.R.color.holo_green_dark) 24 | var needleColor: Int = resources.getColor(android.R.color.holo_orange_dark) 25 | 26 | var defaultStartLoading: Boolean = true 27 | 28 | var needlePivotX: Float = 0.0f 29 | private set 30 | get() { 31 | return needleJointRadius.toFloat() 32 | } 33 | 34 | var needlePivotY: Float = 0.0f 35 | private set 36 | get() { 37 | return (needleView.height - needleJointRadius).toFloat() 38 | } 39 | 40 | private lateinit var lowerRangeArcView: ArcView 41 | private lateinit var higherRangeArcView: ArcView 42 | 43 | private lateinit var needleView: NeedleView 44 | 45 | 46 | constructor(context: Context) : super(context) { 47 | initView() 48 | } 49 | 50 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 51 | initAttributes(attrs) 52 | initView() 53 | } 54 | 55 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 56 | initAttributes(attrs) 57 | initView() 58 | } 59 | 60 | constructor(context: Context, rangeIndicatorRadius: Int, 61 | rangeIndicatorWidth: Int, needleWidth: Int, 62 | needleJointRadius: Int, lowerRangeColor: Int, 63 | higherRangeColor: Int, needleColor: Int, defaultStartLoading: Boolean) : super(context) { 64 | this.rangeIndicatorRadius = rangeIndicatorRadius 65 | this.rangeIndicatorWidth = rangeIndicatorWidth 66 | this.needleWidth = needleWidth 67 | this.needleJointRadius = needleJointRadius 68 | this.lowerRangeColor = lowerRangeColor 69 | this.higherRangeColor = higherRangeColor 70 | this.needleColor = needleColor 71 | this.defaultStartLoading = defaultStartLoading 72 | initView() 73 | } 74 | 75 | override fun initAttributes(attrs: AttributeSet) { 76 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.GaugeLoader, 0, 0) 77 | 78 | this.rangeIndicatorRadius = typedArray 79 | .getDimensionPixelSize(R.styleable.GaugeLoader_gauge_rangeIndicatorRadius, 140) 80 | 81 | this.rangeIndicatorWidth = typedArray 82 | .getDimensionPixelSize(R.styleable.GaugeLoader_gauge_rangeIndicatorWidth, 100) 83 | 84 | this.needleWidth = typedArray 85 | .getDimensionPixelSize(R.styleable.GaugeLoader_gauge_needleWidth, 20) 86 | 87 | this.needleJointRadius = typedArray 88 | .getDimensionPixelSize(R.styleable.GaugeLoader_gauge_needleJointRadius, 45) 89 | 90 | this.lowerRangeColor = typedArray 91 | .getColor(R.styleable.GaugeLoader_gauge_lowerRangeColor, resources.getColor(android.R.color.holo_green_light)) 92 | 93 | this.higherRangeColor = typedArray 94 | .getColor(R.styleable.GaugeLoader_gauge_higherRangeColor, resources.getColor(android.R.color.holo_green_dark)) 95 | 96 | this.needleColor = typedArray 97 | .getColor(R.styleable.GaugeLoader_gauge_needleColor, resources.getColor(android.R.color.holo_orange_dark)) 98 | 99 | this.defaultStartLoading = typedArray 100 | .getBoolean(R.styleable.GaugeLoader_gauge_defaultStartLoading, true) 101 | 102 | typedArray.recycle() 103 | } 104 | 105 | private fun initView() { 106 | removeAllViews() 107 | removeAllViewsInLayout() 108 | 109 | lowerRangeArcView = ArcView(context, rangeIndicatorRadius, rangeIndicatorWidth, 110 | 150.0f, 155.0f, lowerRangeColor, true, false) 111 | 112 | higherRangeArcView = ArcView(context, rangeIndicatorRadius, rangeIndicatorWidth, 113 | 300.0f, 90.0f, higherRangeColor, true, false) 114 | 115 | 116 | val arcLayoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 117 | ViewGroup.LayoutParams.WRAP_CONTENT) 118 | arcLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE) 119 | 120 | addView(lowerRangeArcView, arcLayoutParams) 121 | addView(higherRangeArcView, arcLayoutParams) 122 | 123 | needleView = NeedleView(context, (rangeIndicatorRadius - needleJointRadius), needleWidth, 124 | needleJointRadius, needleColor) 125 | 126 | val needleLayoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 127 | ViewGroup.LayoutParams.WRAP_CONTENT) 128 | 129 | needleLayoutParams.topMargin = rangeIndicatorWidth / 2 130 | needleLayoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE) 131 | 132 | addView(needleView, needleLayoutParams) 133 | 134 | if (defaultStartLoading) { 135 | 136 | val viewTreeObserver = this.viewTreeObserver 137 | val loaderView = this 138 | 139 | viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { 140 | override fun onGlobalLayout() { 141 | startLoading(null) 142 | 143 | val vto = loaderView.viewTreeObserver 144 | vto.removeOnGlobalLayoutListener(this) 145 | } 146 | }) 147 | } 148 | } 149 | 150 | fun startLoading(animation: Animation?) { 151 | 152 | var rotateAnim = animation 153 | 154 | if (rotateAnim == null) { 155 | rotateAnim = getRotateAnimation() 156 | 157 | rotateAnim.setAnimationListener(object : Animation.AnimationListener { 158 | override fun onAnimationRepeat(anim: Animation?) { 159 | } 160 | 161 | override fun onAnimationEnd(anim: Animation?) { 162 | startLoading(null) 163 | } 164 | 165 | override fun onAnimationStart(anim: Animation?) { 166 | } 167 | }) 168 | } 169 | 170 | needleView.startAnimation(rotateAnim) 171 | } 172 | 173 | fun getRotateAnimation(): RotateAnimation { 174 | 175 | val toDegree = (30..90).random() 176 | val animDuration = (500..1000).random() 177 | 178 | val anim = RotateAnimation(-90.0f, toDegree.toFloat(), 179 | needlePivotX, 180 | needlePivotY) 181 | 182 | anim.duration = animDuration.toLong() 183 | anim.repeatCount = 1 184 | anim.repeatMode = Animation.REVERSE 185 | 186 | val random = (0..6).random() 187 | when (random) { 188 | 0 -> anim.interpolator = LinearInterpolator() 189 | 1 -> anim.interpolator = AccelerateInterpolator() 190 | 2 -> anim.interpolator = DecelerateInterpolator() 191 | 3 -> anim.interpolator = AccelerateDecelerateInterpolator() 192 | 4 -> anim.interpolator = AnticipateInterpolator() 193 | 5 -> anim.interpolator = OvershootInterpolator() 194 | 6 -> anim.interpolator = AnticipateOvershootInterpolator() 195 | } 196 | 197 | return anim 198 | } 199 | 200 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/MultipleRippleLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.content.Context 4 | import android.os.Handler 5 | import android.util.AttributeSet 6 | import android.view.Gravity 7 | import android.view.View 8 | import android.view.ViewTreeObserver 9 | import android.view.animation.AnimationUtils 10 | import android.widget.RelativeLayout 11 | import com.agrawalsuneet.loaderspack.R 12 | import com.agrawalsuneet.loaderspack.basicviews.CircleView 13 | import com.agrawalsuneet.loaderspack.contracts.RippleAbstractView 14 | 15 | /** 16 | * Created by suneet on 04/28/18. 17 | */ 18 | class MultipleRippleLoader : RippleAbstractView { 19 | 20 | var noOfRipples: Int = 3 21 | 22 | private lateinit var rippleCircles: Array 23 | 24 | constructor(context: Context) : super(context) { 25 | initView() 26 | } 27 | 28 | 29 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 30 | initAttributes(attrs) 31 | initView() 32 | } 33 | 34 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 35 | initAttributes(attrs) 36 | initView() 37 | } 38 | 39 | constructor(context: Context, circleInitialRadius: Int, circleColor: Int, noOfRipples: Int) : super(context) { 40 | this.circleInitialRadius = circleInitialRadius 41 | this.circleColor = circleColor 42 | this.noOfRipples = noOfRipples 43 | initView() 44 | } 45 | 46 | override fun initAttributes(attrs: AttributeSet) { 47 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.MultipleRippleLoader, 0, 0) 48 | 49 | circleInitialRadius = typedArray 50 | .getDimensionPixelSize(R.styleable.MultipleRippleLoader_multipleripple_circleInitialRadius, 40) 51 | 52 | circleColor = typedArray.getColor(R.styleable.MultipleRippleLoader_multipleripple_circleColor, 53 | resources.getColor(android.R.color.holo_red_dark)) 54 | 55 | noOfRipples = typedArray.getInteger(R.styleable.MultipleRippleLoader_multipleripple_noOfRipples, 3) 56 | 57 | 58 | fromAlpha = typedArray.getFloat(R.styleable.MultipleRippleLoader_multipleripple_fromAlpha, 0.9f) 59 | toAlpha = typedArray.getFloat(R.styleable.MultipleRippleLoader_multipleripple_toAplha, 0.01f) 60 | 61 | animationDuration = typedArray.getInteger(R.styleable.MultipleRippleLoader_multipleripple_animDuration, 2000) 62 | 63 | interpolator = AnimationUtils.loadInterpolator(context, 64 | typedArray.getResourceId(R.styleable.MultipleRippleLoader_multipleripple_interpolator, 65 | android.R.anim.decelerate_interpolator)) 66 | 67 | typedArray.recycle() 68 | } 69 | 70 | override fun onVisibilityChanged(changedView: View, visibility: Int) { 71 | super.onVisibilityChanged(changedView, visibility) 72 | 73 | 74 | for (pos in 0 until noOfRipples) { 75 | rippleCircles[pos]?.clearAnimation() 76 | } 77 | 78 | if (visibility == View.VISIBLE) { 79 | startLoading() 80 | } 81 | } 82 | 83 | override fun initView() { 84 | removeAllViews() 85 | removeAllViewsInLayout() 86 | 87 | this.gravity = Gravity.CENTER 88 | 89 | val relativeLayout = RelativeLayout(context) 90 | 91 | relativeLayout.gravity = Gravity.CENTER 92 | 93 | val relParam = RelativeLayout.LayoutParams( 94 | 4 * circleInitialRadius, 95 | 4 * circleInitialRadius) 96 | 97 | this.addView(relativeLayout, relParam) 98 | 99 | rippleCircles = arrayOfNulls(noOfRipples) 100 | 101 | for (i in 0 until noOfRipples) { 102 | val circle = CircleView(context, circleInitialRadius, circleColor) 103 | relativeLayout.addView(circle) 104 | 105 | circle.visibility = View.INVISIBLE 106 | rippleCircles[i] = circle 107 | } 108 | 109 | viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { 110 | override fun onGlobalLayout() { 111 | startLoading() 112 | 113 | this@MultipleRippleLoader.viewTreeObserver.removeOnGlobalLayoutListener(this) 114 | } 115 | }) 116 | } 117 | 118 | override fun startLoading() { 119 | for (i in 0 until noOfRipples) { 120 | 121 | Handler().postDelayed({ 122 | val animSet = getAnimSet() 123 | rippleCircles[i]?.startAnimation(animSet) 124 | 125 | }, ((i * animationDuration) / noOfRipples).toLong()) 126 | } 127 | } 128 | 129 | 130 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/PulseLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.content.Context 4 | import android.graphics.Canvas 5 | import android.graphics.Paint 6 | import android.util.AttributeSet 7 | import android.view.View 8 | import com.agrawalsuneet.loaderspack.R 9 | import com.agrawalsuneet.loaderspack.contracts.LoaderContract 10 | 11 | /** 12 | * Created by agrawalsuneet on 10/6/18. 13 | */ 14 | 15 | class PulseLoader : View, LoaderContract { 16 | 17 | var pulseLineThickness: Int = 15 18 | var sideLength: Int = 300 19 | 20 | var normalIncrementalValue: Float = 4.0f 21 | set(value) { 22 | field = if (value <= 0) 1.0f else value 23 | } 24 | 25 | var pulseIncrementalValue: Float = 20.0f 26 | set(value) { 27 | field = if (value <= 0) 1.0f else value 28 | } 29 | 30 | var pulseColor: Int = resources.getColor(android.R.color.holo_green_light) 31 | 32 | private val paint: Paint = Paint() 33 | 34 | private var step: Int = 0 35 | private val maxSteps: Int = 6 36 | 37 | private var currentXValue = 0.0f 38 | private var currentYValue = 0.0f 39 | 40 | private var posArray = Array(maxSteps) { LineCordinates() } 41 | 42 | constructor(context: Context) : super(context) { 43 | initValues() 44 | } 45 | 46 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 47 | initAttributes(attrs) 48 | initValues() 49 | } 50 | 51 | constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) { 52 | initAttributes(attrs) 53 | initValues() 54 | } 55 | 56 | constructor(context: Context, pulseLineThickness: Int, sideLength: Int, normalIncrementalValue: Float, 57 | pulseIncrementalValue: Float, pulseColor: Int) : super(context) { 58 | this.pulseLineThickness = pulseLineThickness 59 | this.sideLength = sideLength 60 | this.normalIncrementalValue = normalIncrementalValue 61 | this.pulseIncrementalValue = pulseIncrementalValue 62 | this.pulseColor = pulseColor 63 | initValues() 64 | } 65 | 66 | override fun initAttributes(attrs: AttributeSet) { 67 | 68 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.PulseLoader) 69 | 70 | pulseLineThickness = typedArray.getDimensionPixelSize(R.styleable.PulseLoader_pulse_LineThickness, 15) 71 | sideLength = typedArray.getDimensionPixelSize(R.styleable.PulseLoader_pulse_sideLength, 300) 72 | 73 | normalIncrementalValue = typedArray.getFloat(R.styleable.PulseLoader_pulse_normalIncrementalValue, 4.0f) 74 | 75 | pulseIncrementalValue = typedArray.getFloat(R.styleable.PulseLoader_pulse_pulseIncrementalValue, 20.0f) 76 | 77 | pulseColor = typedArray 78 | .getColor(R.styleable.PulseLoader_pulse_pulseColor, resources.getColor(android.R.color.holo_green_light)) 79 | 80 | typedArray.recycle() 81 | } 82 | 83 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 84 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 85 | 86 | 87 | val calWidth = (2 * sideLength) + (8 * pulseLineThickness) 88 | val calHeight = (20 * pulseLineThickness) 89 | setMeasuredDimension(calWidth, calHeight) 90 | } 91 | 92 | private fun initValues() { 93 | 94 | initCordinates() 95 | 96 | paint.color = pulseColor 97 | paint.isAntiAlias = true 98 | 99 | paint.style = Paint.Style.FILL 100 | paint.strokeWidth = pulseLineThickness.toFloat() 101 | paint.strokeCap = Paint.Cap.ROUND 102 | } 103 | 104 | 105 | override fun onDraw(canvas: Canvas) { 106 | super.onDraw(canvas) 107 | 108 | for (pos in 0 until step) { 109 | val lineCordinates = posArray[pos] 110 | canvas.drawLine(lineCordinates.xStartCor, 111 | lineCordinates.yStartCor, 112 | lineCordinates.xEndCor, 113 | lineCordinates.yEndCor, 114 | paint) 115 | } 116 | 117 | // draw current line 118 | val lineCordinates = posArray[step] 119 | canvas.drawLine(lineCordinates.xStartCor, 120 | lineCordinates.yStartCor, 121 | currentXValue, 122 | currentYValue, 123 | paint) 124 | 125 | currentXValue += lineCordinates.xIncrementalValue 126 | currentYValue += lineCordinates.yIncrementalValue 127 | 128 | if (currentXValue >= lineCordinates.xEndCor) { 129 | step = (step + 1) % maxSteps 130 | currentXValue = posArray[step].xStartCor 131 | currentYValue = posArray[step].yStartCor 132 | } 133 | 134 | postInvalidateOnAnimation() 135 | } 136 | 137 | private inner class LineCordinates { 138 | var xStartCor = 0.0f 139 | var xEndCor = 0.0f 140 | var yStartCor = 0.0f 141 | var yEndCor = 0.0f 142 | 143 | var xIncrementalValue = 0.0f 144 | var yIncrementalValue = 0.0f 145 | } 146 | 147 | private fun initCordinates() { 148 | for (pos in 0 until maxSteps) { 149 | val lineCordinates = LineCordinates() 150 | 151 | when (pos) { 152 | 0 -> { 153 | lineCordinates.xStartCor = (0.5 * pulseLineThickness).toFloat() 154 | lineCordinates.xEndCor = (sideLength).toFloat() 155 | lineCordinates.yStartCor = (10 * pulseLineThickness).toFloat() 156 | lineCordinates.yEndCor = (10 * pulseLineThickness).toFloat() 157 | 158 | lineCordinates.xIncrementalValue = normalIncrementalValue 159 | } 160 | 161 | 1 -> { 162 | lineCordinates.xStartCor = (sideLength).toFloat() 163 | lineCordinates.xEndCor = (sideLength + (2 * pulseLineThickness)).toFloat() 164 | lineCordinates.yStartCor = (10 * pulseLineThickness).toFloat() 165 | lineCordinates.yEndCor = (0.5 * pulseLineThickness).toFloat() 166 | 167 | lineCordinates.yIncrementalValue = -pulseIncrementalValue 168 | //negative because going up 169 | 170 | lineCordinates.xIncrementalValue = 171 | (((lineCordinates.xEndCor - lineCordinates.xStartCor) * pulseIncrementalValue) 172 | / (lineCordinates.yStartCor - lineCordinates.yEndCor)) 173 | } 174 | 175 | 2 -> { 176 | lineCordinates.xStartCor = (sideLength + (2 * pulseLineThickness)).toFloat() 177 | lineCordinates.xEndCor = sideLength + (5 * pulseLineThickness).toFloat() 178 | lineCordinates.yStartCor = (0.5 * pulseLineThickness).toFloat() 179 | lineCordinates.yEndCor = (19.5 * pulseLineThickness).toFloat() 180 | 181 | lineCordinates.yIncrementalValue = pulseIncrementalValue 182 | 183 | lineCordinates.xIncrementalValue = 184 | (((lineCordinates.xEndCor - lineCordinates.xStartCor) * pulseIncrementalValue) 185 | / (lineCordinates.yEndCor - lineCordinates.yStartCor)) 186 | } 187 | 188 | 3 -> { 189 | lineCordinates.xStartCor = sideLength + (5 * pulseLineThickness).toFloat() 190 | lineCordinates.xEndCor = sideLength + (7 * pulseLineThickness).toFloat() 191 | lineCordinates.yStartCor = (19.5 * pulseLineThickness).toFloat() 192 | lineCordinates.yEndCor = (6 * pulseLineThickness).toFloat() 193 | 194 | lineCordinates.yIncrementalValue = -pulseIncrementalValue 195 | //negative because going up 196 | 197 | lineCordinates.xIncrementalValue = 198 | (((lineCordinates.xEndCor - lineCordinates.xStartCor) * pulseIncrementalValue) 199 | / (lineCordinates.yStartCor - lineCordinates.yEndCor)) 200 | } 201 | 202 | 4 -> { 203 | lineCordinates.xStartCor = sideLength + (7 * pulseLineThickness).toFloat() 204 | lineCordinates.xEndCor = sideLength + (8 * pulseLineThickness).toFloat() 205 | lineCordinates.yStartCor = (6 * pulseLineThickness).toFloat() 206 | lineCordinates.yEndCor = (10 * pulseLineThickness).toFloat() 207 | 208 | lineCordinates.yIncrementalValue = pulseIncrementalValue 209 | 210 | lineCordinates.xIncrementalValue = 211 | (((lineCordinates.xEndCor - lineCordinates.xStartCor) * pulseIncrementalValue) 212 | / (lineCordinates.yEndCor - lineCordinates.yStartCor)) 213 | } 214 | 215 | 5 -> { 216 | lineCordinates.xStartCor = sideLength + (8 * pulseLineThickness).toFloat() 217 | lineCordinates.xEndCor = ((2 * sideLength) 218 | + (8 * pulseLineThickness) 219 | - (pulseLineThickness / 2)).toFloat() 220 | lineCordinates.yStartCor = (10 * pulseLineThickness).toFloat() 221 | lineCordinates.yEndCor = (10 * pulseLineThickness).toFloat() 222 | 223 | lineCordinates.xIncrementalValue = normalIncrementalValue 224 | } 225 | } 226 | 227 | posArray[pos] = lineCordinates 228 | } 229 | 230 | currentXValue = posArray[0].xStartCor 231 | currentYValue = posArray[0].yStartCor 232 | } 233 | 234 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/RingAndCircleLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.Gravity 6 | import android.view.ViewTreeObserver 7 | import android.view.animation.Animation 8 | import android.view.animation.LinearInterpolator 9 | import android.view.animation.RotateAnimation 10 | import android.widget.LinearLayout 11 | import android.widget.RelativeLayout 12 | import com.agrawalsuneet.loaderspack.R 13 | import com.agrawalsuneet.loaderspack.basicviews.CircleView 14 | import com.agrawalsuneet.loaderspack.contracts.LoaderContract 15 | 16 | /** 17 | * Created by agrawalsuneet on 9/7/18. 18 | */ 19 | class RingAndCircleLoader : LinearLayout, LoaderContract { 20 | 21 | var circleRadius: Int = 30 22 | 23 | var ringRadius: Int = 180 24 | var ringWidth: Int = 10 25 | 26 | var circleColor: Int = resources.getColor(android.R.color.holo_green_dark) 27 | var ringColor: Int = resources.getColor(android.R.color.darker_gray) 28 | 29 | var animDuration: Int = 2000 30 | 31 | private lateinit var relativeLayout: RelativeLayout 32 | private lateinit var ringView: CircleView 33 | private lateinit var circleView: CircleView 34 | 35 | private var calWidthHeight: Int = 0 36 | 37 | 38 | constructor(context: Context) : super(context) { 39 | initView() 40 | } 41 | 42 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 43 | initAttributes(attrs) 44 | initView() 45 | } 46 | 47 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 48 | initAttributes(attrs) 49 | initView() 50 | } 51 | 52 | constructor(context: Context?, circleRadius: Int, ringRadius: Int, ringWidth: Int, circleColor: Int, ringColor: Int) : super(context) { 53 | this.circleRadius = circleRadius 54 | this.ringRadius = ringRadius 55 | this.ringWidth = ringWidth 56 | this.circleColor = circleColor 57 | this.ringColor = ringColor 58 | initView() 59 | } 60 | 61 | 62 | override fun initAttributes(attrs: AttributeSet) { 63 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RingAndCircleLoader, 0, 0) 64 | 65 | 66 | this.circleRadius = typedArray.getDimensionPixelSize(R.styleable.RingAndCircleLoader_ringandcircle_circleRadius, 30) 67 | 68 | this.ringRadius = typedArray.getDimensionPixelSize(R.styleable.RingAndCircleLoader_ringandcircle_ringRadius, 180) 69 | this.ringWidth = typedArray.getDimensionPixelSize(R.styleable.RingAndCircleLoader_ringandcircle_ringWidth, 10) 70 | 71 | 72 | this.circleColor = typedArray.getColor(R.styleable.RingAndCircleLoader_ringandcircle_circleColor, 73 | resources.getColor(android.R.color.holo_green_dark)) 74 | 75 | this.ringColor = typedArray.getColor(R.styleable.RingAndCircleLoader_ringandcircle_ringColor, 76 | resources.getColor(android.R.color.darker_gray)) 77 | 78 | this.animDuration = typedArray.getInt(R.styleable.RingAndCircleLoader_ringandcircle_animDuration, 2000) 79 | 80 | typedArray.recycle() 81 | } 82 | 83 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 84 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 85 | 86 | if (calWidthHeight == 0) { 87 | calWidthHeight = (2 * ringRadius) + (2 * circleRadius) 88 | } 89 | 90 | setMeasuredDimension(calWidthHeight, calWidthHeight) 91 | } 92 | 93 | private fun initView() { 94 | removeAllViews() 95 | removeAllViewsInLayout() 96 | 97 | this.gravity = Gravity.CENTER_HORIZONTAL 98 | 99 | relativeLayout = RelativeLayout(context) 100 | relativeLayout.gravity = Gravity.CENTER_HORIZONTAL 101 | 102 | if (calWidthHeight == 0) { 103 | calWidthHeight = (2 * ringRadius) + (2 * circleRadius) 104 | } 105 | 106 | 107 | ringView = CircleView(context, ringRadius, ringColor, true, ringWidth) 108 | 109 | val widthHeight = (2 * ringRadius) + ringWidth 110 | val ringParam = RelativeLayout.LayoutParams(widthHeight, widthHeight) 111 | ringParam.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE) 112 | 113 | relativeLayout.addView(ringView, ringParam) 114 | 115 | circleView = CircleView(context, circleRadius, circleColor) 116 | 117 | val circleParam = RelativeLayout.LayoutParams((2 * circleRadius), (2 * circleRadius)) 118 | circleParam.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE) 119 | 120 | relativeLayout.addView(circleView, circleParam) 121 | 122 | val relParam = LinearLayout.LayoutParams(calWidthHeight, calWidthHeight) 123 | this.addView(relativeLayout, relParam) 124 | 125 | val loaderView = this 126 | 127 | 128 | viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { 129 | override fun onGlobalLayout() { 130 | startLoading() 131 | 132 | val vto = loaderView.viewTreeObserver 133 | vto.removeOnGlobalLayoutListener(this) 134 | } 135 | }) 136 | } 137 | 138 | private fun startLoading() { 139 | val rotateAnimation = getRotateAnim() 140 | circleView.startAnimation(rotateAnimation) 141 | } 142 | 143 | private fun getRotateAnim(): RotateAnimation { 144 | 145 | val rotateAnimation = RotateAnimation(0.0f, 360.0f, 146 | (circleRadius).toFloat(), (ringRadius + circleRadius).toFloat()) 147 | rotateAnimation.duration = animDuration.toLong() 148 | rotateAnimation.fillAfter = true 149 | rotateAnimation.interpolator = LinearInterpolator() 150 | rotateAnimation.repeatCount = Animation.INFINITE 151 | rotateAnimation.repeatMode = Animation.RESTART 152 | 153 | return rotateAnimation 154 | } 155 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/RippleLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.Gravity 6 | import android.view.ViewTreeObserver 7 | import android.view.animation.AnimationUtils 8 | import com.agrawalsuneet.loaderspack.R 9 | import com.agrawalsuneet.loaderspack.basicviews.CircleView 10 | import com.agrawalsuneet.loaderspack.contracts.RippleAbstractView 11 | 12 | /** 13 | * Created by suneet on 11/15/17. 14 | */ 15 | open class RippleLoader : RippleAbstractView { 16 | 17 | 18 | private lateinit var circleView: CircleView 19 | 20 | constructor(context: Context) : super(context) { 21 | initView() 22 | } 23 | 24 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 25 | initAttributes(attrs) 26 | initView() 27 | } 28 | 29 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 30 | initAttributes(attrs) 31 | initView() 32 | } 33 | 34 | override fun initAttributes(attrs: AttributeSet) { 35 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RippleLoader, 0, 0) 36 | 37 | circleInitialRadius = typedArray 38 | .getDimensionPixelSize(R.styleable.RippleLoader_ripple_circleInitialRadius, 40) 39 | 40 | circleColor = typedArray.getColor(R.styleable.RippleLoader_ripple_circleColor, 41 | resources.getColor(android.R.color.holo_red_dark)) 42 | 43 | 44 | fromAlpha = typedArray.getFloat(R.styleable.RippleLoader_ripple_fromAlpha, 0.9f) 45 | toAlpha = typedArray.getFloat(R.styleable.RippleLoader_ripple_toAplha, 0.01f) 46 | 47 | animationDuration = typedArray.getInteger(R.styleable.RippleLoader_ripple_animDuration, 2000) 48 | 49 | interpolator = AnimationUtils.loadInterpolator(context, 50 | typedArray.getResourceId(R.styleable.RippleLoader_ripple_interpolator, 51 | android.R.anim.decelerate_interpolator)) 52 | 53 | typedArray.recycle() 54 | } 55 | 56 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 57 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 58 | 59 | setMeasuredDimension(4 * circleInitialRadius, 4 * circleInitialRadius) 60 | } 61 | 62 | 63 | override fun initView() { 64 | removeAllViews() 65 | removeAllViewsInLayout() 66 | 67 | this.gravity = Gravity.CENTER 68 | circleView = CircleView(context, circleInitialRadius, circleColor) 69 | 70 | addView(circleView) 71 | 72 | viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { 73 | override fun onGlobalLayout() { 74 | startLoading() 75 | 76 | this@RippleLoader.viewTreeObserver.removeOnGlobalLayoutListener(this) 77 | } 78 | }) 79 | } 80 | 81 | override fun startLoading() { 82 | var animSet = getAnimSet() 83 | circleView.startAnimation(animSet) 84 | } 85 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/RotatingCircularSticksLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.ViewTreeObserver 6 | import android.view.animation.Animation 7 | import android.view.animation.LinearInterpolator 8 | import android.view.animation.RotateAnimation 9 | import android.widget.LinearLayout 10 | import com.agrawalsuneet.loaderspack.R 11 | import com.agrawalsuneet.loaderspack.basicviews.CircularSticksBaseView 12 | import com.agrawalsuneet.loaderspack.contracts.LoaderContract 13 | 14 | /** 15 | * Created by suneet on 1/1/18. 16 | */ 17 | class RotatingCircularSticksLoader : LinearLayout, LoaderContract { 18 | 19 | var noOfSticks: Int = 50 20 | 21 | var outerCircleRadius: Float = 200.0f 22 | var innerCircleRadius: Float = 100.0f 23 | 24 | var sticksColor: Int = resources.getColor(android.R.color.darker_gray) 25 | var viewBackgroundColor: Int = resources.getColor(android.R.color.white) 26 | 27 | var animDuration: Int = 5000 28 | 29 | private lateinit var circularSticksBaseView: CircularSticksBaseView 30 | 31 | constructor(context: Context) : super(context) { 32 | initView() 33 | } 34 | 35 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 36 | initAttributes(attrs) 37 | initView() 38 | } 39 | 40 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 41 | initAttributes(attrs) 42 | initView() 43 | } 44 | 45 | constructor(context: Context, noOfSticks: Int, outerCircleRadius: Float, innerCircleRadius: Float, sticksColor: Int, viewBackgroundColor: Int) : super(context) { 46 | this.noOfSticks = noOfSticks 47 | this.outerCircleRadius = outerCircleRadius 48 | this.innerCircleRadius = innerCircleRadius 49 | this.sticksColor = sticksColor 50 | this.viewBackgroundColor = viewBackgroundColor 51 | initView() 52 | } 53 | 54 | override fun initAttributes(attrs: AttributeSet) { 55 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RotatingCircularSticksLoader, 0, 0) 56 | 57 | this.noOfSticks = typedArray 58 | .getInteger(R.styleable.RotatingCircularSticksLoader_rotatingsticks_noOfSticks, 50) 59 | 60 | this.outerCircleRadius = typedArray 61 | .getDimension(R.styleable.RotatingCircularSticksLoader_rotatingsticks_outerCircleRadius, 200.0f) 62 | this.innerCircleRadius = typedArray 63 | .getDimension(R.styleable.RotatingCircularSticksLoader_rotatingsticks_innerCircleRadius, 100.0f) 64 | 65 | 66 | this.sticksColor = typedArray 67 | .getColor(R.styleable.RotatingCircularSticksLoader_rotatingsticks_stickColor, resources.getColor(android.R.color.darker_gray)) 68 | this.viewBackgroundColor = typedArray 69 | .getColor(R.styleable.RotatingCircularSticksLoader_rotatingsticks_viewBackgroundColor, resources.getColor(android.R.color.white)) 70 | 71 | this.animDuration = typedArray 72 | .getInteger(R.styleable.RotatingCircularSticksLoader_rotatingsticks_animDuration, 5000) 73 | 74 | typedArray.recycle() 75 | } 76 | 77 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 78 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 79 | setMeasuredDimension(2 * outerCircleRadius.toInt(), 2 * outerCircleRadius.toInt()) 80 | } 81 | 82 | private fun initView() { 83 | removeAllViews() 84 | removeAllViewsInLayout() 85 | 86 | circularSticksBaseView = CircularSticksBaseView(context, noOfSticks, 87 | outerCircleRadius, innerCircleRadius, 88 | sticksColor, viewBackgroundColor) 89 | 90 | 91 | addView(circularSticksBaseView) 92 | 93 | val loaderView = this 94 | 95 | viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { 96 | override fun onGlobalLayout() { 97 | startLoading() 98 | 99 | val vto = loaderView.viewTreeObserver 100 | vto.removeOnGlobalLayoutListener(this) 101 | } 102 | }) 103 | } 104 | 105 | private fun startLoading() { 106 | 107 | val rotationAnim = getRotateAnimation() 108 | circularSticksBaseView.startAnimation(rotationAnim) 109 | } 110 | 111 | private fun getRotateAnimation(): RotateAnimation { 112 | 113 | val transAnim = RotateAnimation(0f, 360f, 114 | Animation.RELATIVE_TO_SELF, 0.5f, 115 | Animation.RELATIVE_TO_SELF, 0.5f) 116 | transAnim.duration = animDuration.toLong() 117 | transAnim.fillAfter = true 118 | transAnim.repeatCount = Animation.INFINITE 119 | transAnim.repeatMode = Animation.RESTART 120 | transAnim.interpolator = LinearInterpolator() 121 | 122 | return transAnim 123 | } 124 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/SearchLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.ViewTreeObserver 6 | import android.view.animation.* 7 | import android.widget.RelativeLayout 8 | import com.agrawalsuneet.dotsloader.utils.random 9 | import com.agrawalsuneet.loaderspack.R 10 | import com.agrawalsuneet.loaderspack.contracts.LoaderContract 11 | import com.agrawalsuneet.loaderspack.basicviews.MagnifyingGlassView 12 | 13 | /** 14 | * Created by agrawalsuneet on 11/2/18. 15 | */ 16 | 17 | class SearchLoader : RelativeLayout, LoaderContract { 18 | 19 | var lensRadius: Int = 50 20 | var lensBorderWidth: Int = 20 21 | 22 | var lensHandleLength: Int = 80 23 | 24 | var lensColor: Int = resources.getColor(android.R.color.holo_green_light) 25 | 26 | var xRangeToSearch: Int = 400 27 | var yRangeToSearch: Int = 400 28 | 29 | var defaultStartLoading: Boolean = true 30 | 31 | private lateinit var magnifyingGlassView: MagnifyingGlassView 32 | 33 | private var xCor: Float = 0.0f 34 | private var yCor: Float = 0.0f 35 | 36 | 37 | constructor(context: Context) : super(context) { 38 | initView() 39 | } 40 | 41 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 42 | initAttributes(attrs) 43 | initView() 44 | } 45 | 46 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 47 | initAttributes(attrs) 48 | initView() 49 | } 50 | 51 | constructor(context: Context?, lensRadius: Int, lensBorderWidth: Int, lensHandleLength: Int, lensColor: Int, xRangeToSearch: Int, yRangeToSearch: Int, defaultStartLoading: Boolean) : super(context) { 52 | this.lensRadius = lensRadius 53 | this.lensBorderWidth = lensBorderWidth 54 | this.lensHandleLength = lensHandleLength 55 | this.lensColor = lensColor 56 | this.xRangeToSearch = xRangeToSearch 57 | this.yRangeToSearch = yRangeToSearch 58 | this.defaultStartLoading = defaultStartLoading 59 | initView() 60 | } 61 | 62 | 63 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 64 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 65 | 66 | setMeasuredDimension(xRangeToSearch, yRangeToSearch) 67 | } 68 | 69 | 70 | override fun initAttributes(attrs: AttributeSet) { 71 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.SearchLoader, 0, 0) 72 | 73 | this.lensRadius = typedArray 74 | .getDimensionPixelSize(R.styleable.SearchLoader_search_lensRadius, 50) 75 | 76 | this.lensBorderWidth = typedArray 77 | .getDimensionPixelSize(R.styleable.SearchLoader_search_lensBorderWidth, 20) 78 | 79 | this.lensHandleLength = typedArray 80 | .getDimensionPixelSize(R.styleable.SearchLoader_search_lensHandleLength, 80) 81 | 82 | 83 | this.lensColor = typedArray 84 | .getColor(R.styleable.SearchLoader_search_lensColor, resources.getColor(android.R.color.holo_green_light)) 85 | 86 | this.xRangeToSearch = typedArray 87 | .getDimensionPixelSize(R.styleable.SearchLoader_search_xRangeToSearch, 400) 88 | 89 | this.yRangeToSearch = typedArray 90 | .getDimensionPixelSize(R.styleable.SearchLoader_search_yRangeToSearch, 400) 91 | 92 | this.defaultStartLoading = typedArray 93 | .getBoolean(R.styleable.SearchLoader_search_defaultStartLoading, true) 94 | 95 | typedArray.recycle() 96 | } 97 | 98 | private fun initView() { 99 | removeAllViews() 100 | removeAllViewsInLayout() 101 | 102 | magnifyingGlassView = MagnifyingGlassView(context, lensRadius, lensBorderWidth, lensHandleLength, lensColor) 103 | 104 | addView(magnifyingGlassView) 105 | 106 | 107 | if (defaultStartLoading) { 108 | 109 | val viewTreeObserver = this.viewTreeObserver 110 | val loaderView = this 111 | 112 | viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { 113 | override fun onGlobalLayout() { 114 | startLoading(null) 115 | 116 | val vto = loaderView.viewTreeObserver 117 | vto.removeOnGlobalLayoutListener(this) 118 | } 119 | }) 120 | } 121 | } 122 | 123 | fun startLoading(animation: Animation?) { 124 | 125 | var translateAnim = animation 126 | 127 | if (translateAnim == null) { 128 | translateAnim = getTranslateAnimation() 129 | 130 | translateAnim.setAnimationListener(object : Animation.AnimationListener { 131 | override fun onAnimationRepeat(anim: Animation?) { 132 | } 133 | 134 | override fun onAnimationEnd(anim: Animation?) { 135 | startLoading(null) 136 | } 137 | 138 | override fun onAnimationStart(anim: Animation?) { 139 | } 140 | }) 141 | } 142 | 143 | magnifyingGlassView.startAnimation(translateAnim) 144 | } 145 | 146 | private fun getTranslateAnimation(): TranslateAnimation { 147 | 148 | val animDuration = (300..1000).random() 149 | 150 | val maxX = (xRangeToSearch - magnifyingGlassView.width) 151 | val maxY = (yRangeToSearch - magnifyingGlassView.height) 152 | 153 | 154 | val toXCor = (0..(if (maxX > 0) maxX else magnifyingGlassView.width)).random().toFloat() 155 | val toYCor = (0..(if (maxY > 0) maxY else magnifyingGlassView.height)).random().toFloat() 156 | 157 | val anim = TranslateAnimation(xCor, toXCor, yCor, toYCor) 158 | 159 | anim.duration = animDuration.toLong() 160 | anim.repeatCount = 0 161 | anim.fillAfter = true 162 | 163 | val random = (0..3).random() 164 | when (random) { 165 | 0 -> anim.interpolator = LinearInterpolator() 166 | 1 -> anim.interpolator = AccelerateInterpolator() 167 | 2 -> anim.interpolator = DecelerateInterpolator() 168 | 3 -> anim.interpolator = AccelerateDecelerateInterpolator() 169 | } 170 | 171 | xCor = toXCor 172 | yCor = toYCor 173 | 174 | return anim 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/loaders/WifiLoader.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.loaders 2 | 3 | import android.content.Context 4 | import android.graphics.Canvas 5 | import android.graphics.Paint 6 | import android.graphics.RectF 7 | import android.util.AttributeSet 8 | import android.view.View 9 | import com.agrawalsuneet.loaderspack.R 10 | import com.agrawalsuneet.loaderspack.contracts.LoaderContract 11 | 12 | /** 13 | * Created by agrawalsuneet on 9/24/18. 14 | */ 15 | 16 | class WifiLoader : View, LoaderContract { 17 | 18 | var centerCircleRadius: Int = 20 19 | 20 | var wifiColor: Int = resources.getColor(android.R.color.holo_green_light) 21 | 22 | var incrementalAngle: Float = 1.0f 23 | set(value) { 24 | field = if (value < 0.1) 1.0f else value 25 | } 26 | 27 | private val centerCirclePaint: Paint = Paint() 28 | private val sidesPaint: Paint = Paint() 29 | 30 | private var rectfArray = Array(3) { it -> null } 31 | 32 | private var calWidth = 0 33 | private var calHeight = 0 34 | 35 | private var xCor: Float = 0.0f 36 | private var yCor: Float = 0.0f 37 | 38 | private val startAngle: Float = 230.0f 39 | private val sweepAngle: Float = 80.0f 40 | private val waitFrame: Int = 60 41 | 42 | private var currentSweepAngle: Float = 0.0f 43 | private var visibleShapePos: Int = 0 44 | private var isDrawingForward: Boolean = true 45 | 46 | private var currentWaitFrame: Int = 0 47 | 48 | 49 | constructor(context: Context) : super(context) { 50 | initPaints() 51 | initValues() 52 | } 53 | 54 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 55 | initAttributes(attrs) 56 | initPaints() 57 | initValues() 58 | } 59 | 60 | constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 61 | initAttributes(attrs) 62 | initPaints() 63 | initValues() 64 | } 65 | 66 | constructor(context: Context, centerCircleRadius: Int, wifiColor: Int) : super(context) { 67 | this.centerCircleRadius = centerCircleRadius 68 | this.wifiColor = wifiColor 69 | initPaints() 70 | initValues() 71 | } 72 | 73 | override fun initAttributes(attrs: AttributeSet) { 74 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.WifiLoader, 0, 0) 75 | 76 | this.centerCircleRadius = typedArray 77 | .getDimensionPixelSize(R.styleable.WifiLoader_wifi_centerCircleRadius, 20) 78 | 79 | this.wifiColor = typedArray 80 | .getColor(R.styleable.WifiLoader_wifi_wifiColor, resources.getColor(android.R.color.holo_green_light)) 81 | 82 | this.incrementalAngle = typedArray.getFloat(R.styleable.WifiLoader_wifi_incrementalAngle, 1.0f) 83 | 84 | typedArray.recycle() 85 | } 86 | 87 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 88 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 89 | 90 | if (calWidth == 0 || calHeight == 0) { 91 | calWidth = 18 * centerCircleRadius 92 | calHeight = 14 * centerCircleRadius 93 | } 94 | 95 | setMeasuredDimension(calWidth, calHeight) 96 | } 97 | 98 | 99 | private fun initPaints() { 100 | centerCirclePaint.isAntiAlias = true 101 | centerCirclePaint.color = wifiColor 102 | centerCirclePaint.style = Paint.Style.FILL 103 | 104 | 105 | sidesPaint.isAntiAlias = true 106 | sidesPaint.color = wifiColor 107 | sidesPaint.style = Paint.Style.STROKE 108 | sidesPaint.strokeWidth = (2 * centerCircleRadius).toFloat() 109 | sidesPaint.strokeCap = Paint.Cap.ROUND 110 | } 111 | 112 | private fun initValues() { 113 | if (calWidth == 0 || calHeight == 0) { 114 | calWidth = 18 * centerCircleRadius 115 | calHeight = 14 * centerCircleRadius 116 | } 117 | 118 | for (i in 1..3) { 119 | 120 | val acrRectF = RectF().apply { 121 | left = ((calWidth / 2) - (i * 4 * centerCircleRadius)).toFloat() 122 | right = ((calWidth / 2) + (i * 4 * centerCircleRadius)).toFloat() 123 | top = ((calHeight - centerCircleRadius) - (((i * 4)) * centerCircleRadius)).toFloat() 124 | bottom = ((calHeight - centerCircleRadius) + (((i * 4)) * centerCircleRadius)).toFloat() 125 | } 126 | 127 | rectfArray[i - 1] = acrRectF 128 | 129 | } 130 | 131 | xCor = (calWidth / 2).toFloat() 132 | yCor = (calHeight - centerCircleRadius).toFloat() 133 | } 134 | 135 | private fun drawCenterCircle(canvas: Canvas) { 136 | canvas.drawCircle(xCor, yCor, 137 | centerCircleRadius.toFloat(), 138 | centerCirclePaint) 139 | } 140 | 141 | override fun onDraw(canvas: Canvas) { 142 | super.onDraw(canvas) 143 | 144 | when (visibleShapePos) { 145 | 0 -> { 146 | currentWaitFrame++ 147 | if (isDrawingForward) { 148 | if (currentWaitFrame > (waitFrame / 2)) { 149 | drawCenterCircle(canvas) 150 | if (currentWaitFrame > waitFrame) { 151 | visibleShapePos++ 152 | currentWaitFrame = 0 153 | } 154 | } 155 | } else { 156 | if (currentWaitFrame < (waitFrame / 2)) { 157 | drawCenterCircle(canvas) 158 | } else if (currentWaitFrame > waitFrame) { 159 | isDrawingForward = true 160 | currentWaitFrame = 0 161 | } 162 | 163 | } 164 | } 165 | 166 | 1, 2, 3 -> { 167 | 168 | drawCenterCircle(canvas) 169 | 170 | for (i in 1 until visibleShapePos) { 171 | canvas.drawArc(rectfArray.get(i - 1)!!, startAngle, sweepAngle, false, sidesPaint) 172 | } 173 | 174 | canvas.drawArc(rectfArray.get(visibleShapePos - 1)!!, startAngle, currentSweepAngle, false, sidesPaint) 175 | 176 | if (isDrawingForward) { 177 | 178 | if (visibleShapePos <= 3) { 179 | 180 | currentSweepAngle += incrementalAngle 181 | 182 | if (currentSweepAngle >= sweepAngle) { 183 | currentSweepAngle = 0.0f 184 | visibleShapePos++ 185 | } 186 | } 187 | } else { 188 | currentSweepAngle -= incrementalAngle 189 | 190 | if (currentSweepAngle <= 0.0f) { 191 | currentSweepAngle = sweepAngle 192 | visibleShapePos-- 193 | } 194 | 195 | if (visibleShapePos == 0) { 196 | currentSweepAngle = 0.0f 197 | currentWaitFrame = 0 198 | } 199 | } 200 | } 201 | 202 | 4 -> { 203 | drawCenterCircle(canvas) 204 | for (i in 1 until visibleShapePos) { 205 | canvas.drawArc(rectfArray[i - 1]!!, startAngle, sweepAngle, false, sidesPaint) 206 | } 207 | 208 | currentWaitFrame++ 209 | 210 | if (currentWaitFrame > waitFrame) { 211 | visibleShapePos-- 212 | isDrawingForward = false 213 | currentSweepAngle = sweepAngle 214 | } 215 | } 216 | } 217 | 218 | postInvalidateOnAnimation() 219 | } 220 | } -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/utils/Helper.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.dotsloader.utils 2 | 3 | import android.graphics.Color 4 | import java.util.* 5 | 6 | /** 7 | * Created by suneet on 17/7/17. 8 | */ 9 | 10 | object Helper { 11 | 12 | fun adjustAlpha(color: Int, factor: Float): Int { 13 | val alpha = Math.round(Color.alpha(color) * factor) 14 | val red = Color.red(color) 15 | val green = Color.green(color) 16 | val blue = Color.blue(color) 17 | return Color.argb(alpha, red, green, blue) 18 | } 19 | } 20 | 21 | fun ClosedRange.random() = 22 | Random().nextInt((endInclusive + 1) - start) + start 23 | 24 | -------------------------------------------------------------------------------- /loaderspack/src/main/java/com/agrawalsuneet/loaderspack/utils/Utils.kt: -------------------------------------------------------------------------------- 1 | package com.agrawalsuneet.loaderspack.utils 2 | 3 | import android.content.ContextWrapper 4 | import android.app.Activity 5 | import android.content.Context 6 | 7 | 8 | object Utils { 9 | 10 | fun scanForActivity(context: Context?): Activity? { 11 | return when (context) { 12 | null -> null 13 | is Activity -> context 14 | is ContextWrapper -> scanForActivity(context.baseContext) 15 | else -> null 16 | } 17 | 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /loaderspack/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':loaderspack' 2 | --------------------------------------------------------------------------------