Full Code of ybq/Android-SpinKit for AI

master aa83e4d0a42c cached
75 files
120.1 KB
31.2k tokens
304 symbols
1 requests
Download .txt
Repository: ybq/Android-SpinKit
Branch: master
Commit: aa83e4d0a42c
Files: 75
Total size: 120.1 KB

Directory structure:
gitextract_xp6aiyyo/

├── .gitignore
├── LICENSE
├── README.md
├── README_zh-CN.md
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── library/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── github/
│           │           └── ybq/
│           │               └── android/
│           │                   └── spinkit/
│           │                       ├── SpinKitView.java
│           │                       ├── SpriteFactory.java
│           │                       ├── Style.java
│           │                       ├── animation/
│           │                       │   ├── AnimationUtils.java
│           │                       │   ├── FloatProperty.java
│           │                       │   ├── IntProperty.java
│           │                       │   ├── SpriteAnimatorBuilder.java
│           │                       │   └── interpolator/
│           │                       │       ├── Ease.java
│           │                       │       ├── KeyFrameInterpolator.java
│           │                       │       ├── PathInterpolatorCompat.java
│           │                       │       ├── PathInterpolatorCompatApi21.java
│           │                       │       ├── PathInterpolatorCompatBase.java
│           │                       │       └── PathInterpolatorDonut.java
│           │                       ├── sprite/
│           │                       │   ├── CircleLayoutContainer.java
│           │                       │   ├── CircleSprite.java
│           │                       │   ├── RectSprite.java
│           │                       │   ├── RingSprite.java
│           │                       │   ├── ShapeSprite.java
│           │                       │   ├── Sprite.java
│           │                       │   └── SpriteContainer.java
│           │                       └── style/
│           │                           ├── ChasingDots.java
│           │                           ├── Circle.java
│           │                           ├── CubeGrid.java
│           │                           ├── DoubleBounce.java
│           │                           ├── FadingCircle.java
│           │                           ├── FoldingCube.java
│           │                           ├── MultiplePulse.java
│           │                           ├── MultiplePulseRing.java
│           │                           ├── Pulse.java
│           │                           ├── PulseRing.java
│           │                           ├── RotatingCircle.java
│           │                           ├── RotatingPlane.java
│           │                           ├── ThreeBounce.java
│           │                           ├── WanderingCubes.java
│           │                           └── Wave.java
│           └── res/
│               └── values/
│                   ├── attrs.xml
│                   └── styles.xml
├── sample/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── github/
│           │           └── ybq/
│           │               └── android/
│           │                   └── loading/
│           │                       ├── ArgbEvaluator.java
│           │                       ├── Colors.java
│           │                       ├── DetailActivity.java
│           │                       ├── MainActivity.java
│           │                       ├── SquareFrameLayout.java
│           │                       ├── StyleFragment.java
│           │                       └── WidgetFragment.java
│           └── res/
│               ├── layout/
│               │   ├── activity_detail.xml
│               │   ├── activity_main.xml
│               │   ├── fragment_style.xml
│               │   ├── fragment_widget.xml
│               │   ├── item_pager.xml
│               │   └── item_style.xml
│               ├── values/
│               │   ├── colors.xml
│               │   ├── dimens.xml
│               │   ├── strings.xml
│               │   └── styles.xml
│               └── values-v21/
│                   └── styles.xml
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Built application files
*.apk
*.ap_

# Files for the Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/
out/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
captures/

# Intellij
*.iml
.idea
# Keystore files
*.jks

================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright © 2016 ybq

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

================================================
FILE: README.md
================================================
# Android-SpinKit
>Android loading animations(I wrote a android edition according [SpinKit](https://tobiasahlin.com/spinkit))

[Demo Apk](https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/spinkit.apk)

## Preview

<img src="https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/screen.gif" width="240px" height="240px"/>

<img src="https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/screen2.gif" width="200px" height="200px"/>

## Gradle Dependency

 ``` gradle
dependencies {
    implementation 'com.github.ybq:Android-SpinKit:1.4.0'
 }
 ```


## Usage
- Xml

 ```xml
<com.github.ybq.android.spinkit.SpinKitView
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/spin_kit"
     style="@style/SpinKitView.Large.Circle"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_gravity="center"
     app:SpinKit_Color="@color/colorAccent" />         
```
 
- ProgressBar

 ```java
ProgressBar progressBar = (ProgressBar)findViewById(R.id.progress);
Sprite doubleBounce = new DoubleBounce();
progressBar.setIndeterminateDrawable(doubleBounce);
```

## Style
> 
 ```xml
@style/SpinKitView
@style/SpinKitView.Circle
@style/SpinKitView.Large
@style/SpinKitView.Small
@style/SpinKitView.Small.DoubleBounce   
 ```

Style | Preview
------------     |   -------------
RotatingPlane    | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/RotatingPlane.gif' alt='RotatingPlane' width="90px" height="90px"/>
DoubleBounce     | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/DoubleBounce.gif' alt='DoubleBounce' width="90px" height="90px"/>
Wave             | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/Wave.gif' alt='Wave' width="90px" height="90px"/>
WanderingCubes   | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/WanderingCubes.gif' alt='WanderingCubes' width="90px" height="90px"/>
Pulse            | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/Pulse.gif' alt='Pulse' width="90px" height="90px"/>
ChasingDots      | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/ChasingDots.gif' alt='ChasingDots' width="90px" height="90px"/>
ThreeBounce      | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/ThreeBounce.gif' alt='ThreeBounce' width="90px" height="90px"/>
Circle           | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/Circle.gif' alt='Circle' width="90px" height="90px"/>
CubeGrid         | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/CubeGrid.gif' alt='CubeGrid' width="90px" height="90px"/>
FadingCircle     | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/FadingCircle.gif' alt='FadingCircle' width="90px" height="90px"/>
FoldingCube      | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/FoldingCube.gif' alt='FoldingCube' width="90px" height="90px"/>
RotatingCircle   | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/RotatingCircle.gif' alt='RotatingCircle' width="90px" height="90px"/>







## Acknowledgements
- [SpinKit](https://github.com/tobiasahlin/SpinKit).





================================================
FILE: README_zh-CN.md
================================================

# Android-SpinKit
 
> Android 加载动画([SpinKit](https://tobiasahlin.com/spinkit)的Android版本实现)

[Demo Apk](https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/spinkit.apk)

## 效果

<img src="https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/screen.gif" width="240px" height="240px"/>
 

<img src="https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/screen2.gif" width="200px" height="200px"/>

## Gradle 依赖


 ``` gradle
dependencies {
    implementation 'com.github.ybq:Android-SpinKit:1.4.0'
 }
 ```


## 使用
- Xml

 ```xml
<com.github.ybq.android.spinkit.SpinKitView
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/spin_kit"
     style="@style/SpinKitView.Large.Circle"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_gravity="center"
     app:SpinKit_Color="@color/colorAccent" />         
 ```
 
 
- ProgressBar

 ```java
ProgressBar progressBar = (ProgressBar)findViewById(R.id.progress);
DoubleBounce doubleBounce = new DoubleBounce();
progressBar.setIndeterminateDrawable(doubleBounce);
```

###样式:

样式 | 预览
------------     |   -------------
RotatingPlane    | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/RotatingPlane.gif' alt='RotatingPlane' width="90px" height="90px"/>
DoubleBounce     | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/DoubleBounce.gif' alt='DoubleBounce' width="90px" height="90px"/>
Wave             | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/Wave.gif' alt='Wave' width="90px" height="90px"/>
WanderingCubes   | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/WanderingCubes.gif' alt='WanderingCubes' width="90px" height="90px"/>
Pulse            | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/Pulse.gif' alt='Pulse' width="90px" height="90px"/>
ChasingDots      | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/ChasingDots.gif' alt='ChasingDots' width="90px" height="90px"/>
ThreeBounce      | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/ThreeBounce.gif' alt='ThreeBounce' width="90px" height="90px"/>
Circle           | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/Circle.gif' alt='Circle' width="90px" height="90px"/>
CubeGrid         | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/CubeGrid.gif' alt='CubeGrid' width="90px" height="90px"/>
FadingCircle     | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/FadingCircle.gif' alt='FadingCircle' width="90px" height="90px"/>
FoldingCube      | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/FoldingCube.gif' alt='FoldingCube' width="90px" height="90px"/>
RotatingCircle   | <img src='https://raw.githubusercontent.com/ybq/AndroidSpinKit/master/art/RotatingCircle.gif' alt='RotatingCircle' width="90px" height="90px"/>







##感谢
- [SpinKit](https://github.com/tobiasahlin/SpinKit).





================================================
FILE: build.gradle
================================================
buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
        classpath 'com.novoda:bintray-release:0.8.1'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Tue Nov 14 15:17:22 WET 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip


================================================
FILE: gradle.properties
================================================
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.enableJetifier=true
android.useAndroidX=true

================================================
FILE: gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: library/.gitignore
================================================
/build


================================================
FILE: library/build.gradle
================================================
apply plugin: 'com.android.library'
apply plugin: 'com.novoda.bintray-release'

android {

    compileSdkVersion 28
    buildToolsVersion '28.0.3'

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 28
    }

    lintOptions {
        abortOnError false
    }
}


publish {
    userOrg = 'ybq'
    groupId = 'com.github.ybq'
    artifactId = 'Android-SpinKit'
    publishVersion = '1.4.0'
    desc = 'Android loading animations'
    website = 'https://github.com/ybq/Android-SpinKit'
    licences = ['MIT']
}

================================================
FILE: library/gradle.properties
================================================


================================================
FILE: library/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/ybq/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: library/src/main/AndroidManifest.xml
================================================
<manifest package="com.github.ybq.android.spinkit" />


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/SpinKitView.java
================================================
package com.github.ybq.android.spinkit;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ProgressBar;

import com.github.ybq.android.spinkit.sprite.Sprite;

/**
 * Created by ybq.
 */
public class SpinKitView extends ProgressBar {

    private Style mStyle;
    private int mColor;
    private Sprite mSprite;

    public SpinKitView(Context context) {
        this(context, null);
    }

    public SpinKitView(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.SpinKitViewStyle);
    }

    public SpinKitView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, R.style.SpinKitView);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public SpinKitView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SpinKitView, defStyleAttr,
                defStyleRes);
        mStyle = Style.values()[a.getInt(R.styleable.SpinKitView_SpinKit_Style, 0)];
        mColor = a.getColor(R.styleable.SpinKitView_SpinKit_Color, Color.WHITE);
        a.recycle();
        init();
        setIndeterminate(true);
    }

    private void init() {
        Sprite sprite = SpriteFactory.create(mStyle);
        sprite.setColor(mColor);
        setIndeterminateDrawable(sprite);
    }

    @Override
    public void setIndeterminateDrawable(Drawable d) {
        if (!(d instanceof Sprite)) {
            throw new IllegalArgumentException("this d must be instanceof Sprite");
        }
        setIndeterminateDrawable((Sprite) d);
    }

    public void setIndeterminateDrawable(Sprite d) {
        super.setIndeterminateDrawable(d);
        mSprite = d;
        if (mSprite.getColor() == 0) {

            mSprite.setColor(mColor);
        }
        onSizeChanged(getWidth(), getHeight(), getWidth(), getHeight());
        if (getVisibility() == VISIBLE) {

            mSprite.start();
        }
    }

    @Override
    public Sprite getIndeterminateDrawable() {
        return mSprite;
    }

    public void setColor(int color) {
        this.mColor = color;
        if (mSprite != null) {

            mSprite.setColor(color);
        }
        invalidate();
    }

    @Override
    public void unscheduleDrawable(Drawable who) {
        super.unscheduleDrawable(who);
        if (who instanceof Sprite) {

            ((Sprite) who).stop();
        }
    }

    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        if (hasWindowFocus) {
            if (mSprite != null && getVisibility() == VISIBLE) {

                mSprite.start();
            }
        }
    }

    @Override
    public void onScreenStateChanged(int screenState) {
        super.onScreenStateChanged(screenState);
        if (screenState == View.SCREEN_STATE_OFF) {

            if (mSprite != null) {

                mSprite.stop();
            }
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/SpriteFactory.java
================================================
package com.github.ybq.android.spinkit;

import com.github.ybq.android.spinkit.sprite.Sprite;
import com.github.ybq.android.spinkit.style.ChasingDots;
import com.github.ybq.android.spinkit.style.Circle;
import com.github.ybq.android.spinkit.style.CubeGrid;
import com.github.ybq.android.spinkit.style.DoubleBounce;
import com.github.ybq.android.spinkit.style.FadingCircle;
import com.github.ybq.android.spinkit.style.FoldingCube;
import com.github.ybq.android.spinkit.style.MultiplePulse;
import com.github.ybq.android.spinkit.style.MultiplePulseRing;
import com.github.ybq.android.spinkit.style.Pulse;
import com.github.ybq.android.spinkit.style.PulseRing;
import com.github.ybq.android.spinkit.style.RotatingCircle;
import com.github.ybq.android.spinkit.style.RotatingPlane;
import com.github.ybq.android.spinkit.style.ThreeBounce;
import com.github.ybq.android.spinkit.style.WanderingCubes;
import com.github.ybq.android.spinkit.style.Wave;

/**
 * Created by ybq.
 */
public class SpriteFactory {

    public static Sprite create(Style style) {
        Sprite sprite = null;
        switch (style) {
            case ROTATING_PLANE:
                sprite = new RotatingPlane();
                break;
            case DOUBLE_BOUNCE:
                sprite = new DoubleBounce();
                break;
            case WAVE:
                sprite = new Wave();
                break;
            case WANDERING_CUBES:
                sprite = new WanderingCubes();
                break;
            case PULSE:
                sprite = new Pulse();
                break;
            case CHASING_DOTS:
                sprite = new ChasingDots();
                break;
            case THREE_BOUNCE:
                sprite = new ThreeBounce();
                break;
            case CIRCLE:
                sprite = new Circle();
                break;
            case CUBE_GRID:
                sprite = new CubeGrid();
                break;
            case FADING_CIRCLE:
                sprite = new FadingCircle();
                break;
            case FOLDING_CUBE:
                sprite = new FoldingCube();
                break;
            case ROTATING_CIRCLE:
                sprite = new RotatingCircle();
                break;
            case MULTIPLE_PULSE:
                sprite = new MultiplePulse();
                break;
            case PULSE_RING:
                sprite = new PulseRing();
                break;
            case MULTIPLE_PULSE_RING:
                sprite = new MultiplePulseRing();
                break;
            default:
                break;
        }
        return sprite;
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/Style.java
================================================
package com.github.ybq.android.spinkit;

/**
 * Created by ybq.
 */
public enum Style {

    ROTATING_PLANE(0),
    DOUBLE_BOUNCE(1),
    WAVE(2),
    WANDERING_CUBES(3),
    PULSE(4),
    CHASING_DOTS(5),
    THREE_BOUNCE(6),
    CIRCLE(7),
    CUBE_GRID(8),
    FADING_CIRCLE(9),
    FOLDING_CUBE(10),
    ROTATING_CIRCLE(11),
    MULTIPLE_PULSE(12),
    PULSE_RING(13),
    MULTIPLE_PULSE_RING(14);

    @SuppressWarnings({"FieldCanBeLocal", "unused"})
    private int value;

    Style(int value) {
        this.value = value;
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/AnimationUtils.java
================================================
package com.github.ybq.android.spinkit.animation;

import android.animation.Animator;
import android.animation.ValueAnimator;

import com.github.ybq.android.spinkit.sprite.Sprite;

/**
 * Created by ybq.
 */
public class AnimationUtils {

    public static void start(Animator animator) {
        if (animator != null && !animator.isStarted()) {
            animator.start();
        }
    }

    public static void stop(Animator animator) {
        if (animator != null && !animator.isRunning()) {
            animator.end();
        }
    }

    public static void start(Sprite... sprites) {
        for (Sprite sprite : sprites) {
            sprite.start();
        }
    }

    public static void stop(Sprite... sprites) {
        for (Sprite sprite : sprites) {
            sprite.stop();
        }
    }

    public static boolean isRunning(Sprite... sprites) {
        for (Sprite sprite : sprites) {
            if (sprite.isRunning()) {
                return true;
            }
        }
        return false;
    }

    public static boolean isRunning(ValueAnimator animator) {
        return animator != null && animator.isRunning();
    }

    public static boolean isStarted(ValueAnimator animator) {
        return animator != null && animator.isStarted();
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/FloatProperty.java
================================================
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.ybq.android.spinkit.animation;

import android.util.Property;

/**
 * An implementation of {@link android.util.Property} to be used specifically with fields of type
 * <code>float</code>. This type-specific subclass enables performance benefit by allowing
 * calls to a {@link #set(Object, Float) set()} function that takes the primitive
 * <code>float</code> type and avoids autoboxing and other overhead associated with the
 * <code>Float</code> class.
 *
 * @param <T> The class on which the Property is declared.
 */
public abstract class FloatProperty<T> extends Property<T, Float> {

    public FloatProperty(String name) {
        super(Float.class, name);
    }

    /**
     * A type-specific override of the {@link #set(Object, Float)} that is faster when dealing
     * with fields of type <code>float</code>.
     */
    public abstract void setValue(T object, float value);

    @Override
    final public void set(T object, Float value) {
        setValue(object, value);
    }

}

================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/IntProperty.java
================================================
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.ybq.android.spinkit.animation;

import android.util.Property;

/**
 * An implementation of {@link android.util.Property} to be used specifically with fields of type
 * <code>int</code>. This type-specific subclass enables performance benefit by allowing
 * calls to a {@link #set(Object, Integer) set()} function that takes the primitive
 * <code>int</code> type and avoids autoboxing and other overhead associated with the
 * <code>Integer</code> class.
 *
 * @param <T> The class on which the Property is declared.
 */
public abstract class IntProperty<T> extends Property<T, Integer> {

    public IntProperty(String name) {
        super(Integer.class, name);
    }

    /**
     * A type-specific override of the {@link #set(Object, Integer)} that is faster when dealing
     * with fields of type <code>int</code>.
     */
    public abstract void setValue(T object, int value);

    @Override
    final public void set(T object, Integer value) {
        setValue(object, value);
    }

}

================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/SpriteAnimatorBuilder.java
================================================
package com.github.ybq.android.spinkit.animation;

import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.util.Log;
import android.util.Property;
import android.view.animation.Animation;
import android.view.animation.Interpolator;

import com.github.ybq.android.spinkit.animation.interpolator.KeyFrameInterpolator;
import com.github.ybq.android.spinkit.sprite.Sprite;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * Created by ybq.
 */
public class SpriteAnimatorBuilder {

    private static final String TAG = "SpriteAnimatorBuilder";
    private Sprite sprite;
    private Interpolator interpolator;
    private int repeatCount = Animation.INFINITE;
    private long duration = 2000;
    private int startFrame = 0;
    private Map<String, FrameData> fds = new HashMap<>();


    class FrameData<T> {
        public FrameData(float[] fractions, Property property, T[] values) {
            this.fractions = fractions;
            this.property = property;
            this.values = values;
        }

        float[] fractions;
        Property property;
        T[] values;
    }

    class IntFrameData extends FrameData<Integer> {

        public IntFrameData(float[] fractions, Property property, Integer[] values) {
            super(fractions, property, values);
        }
    }

    class FloatFrameData extends FrameData<Float> {

        public FloatFrameData(float[] fractions, Property property, Float[] values) {
            super(fractions, property, values);
        }
    }

    public SpriteAnimatorBuilder(Sprite sprite) {
        this.sprite = sprite;
    }

    public SpriteAnimatorBuilder scale(float fractions[], Float... scale) {
        holder(fractions, Sprite.SCALE, scale);
        return this;
    }

    public SpriteAnimatorBuilder alpha(float fractions[], Integer... alpha) {
        holder(fractions, Sprite.ALPHA, alpha);
        return this;
    }

    @SuppressWarnings("unused")
    public SpriteAnimatorBuilder scaleX(float fractions[], Float... scaleX) {
        holder(fractions, Sprite.SCALE, scaleX);
        return this;
    }

    public SpriteAnimatorBuilder scaleY(float fractions[], Float... scaleY) {
        holder(fractions, Sprite.SCALE_Y, scaleY);
        return this;
    }

    public SpriteAnimatorBuilder rotateX(float fractions[], Integer... rotateX) {
        holder(fractions, Sprite.ROTATE_X, rotateX);
        return this;
    }

    public SpriteAnimatorBuilder rotateY(float fractions[], Integer... rotateY) {
        holder(fractions, Sprite.ROTATE_Y, rotateY);
        return this;
    }

    @SuppressWarnings("unused")
    public SpriteAnimatorBuilder translateX(float fractions[], Integer... translateX) {
        holder(fractions, Sprite.TRANSLATE_X, translateX);
        return this;
    }


    @SuppressWarnings("unused")
    public SpriteAnimatorBuilder translateY(float fractions[], Integer... translateY) {
        holder(fractions, Sprite.TRANSLATE_Y, translateY);
        return this;
    }


    public SpriteAnimatorBuilder rotate(float fractions[], Integer... rotate) {
        holder(fractions, Sprite.ROTATE, rotate);
        return this;
    }

    public SpriteAnimatorBuilder translateXPercentage(float fractions[], Float... translateXPercentage) {
        holder(fractions, Sprite.TRANSLATE_X_PERCENTAGE, translateXPercentage);
        return this;
    }

    public SpriteAnimatorBuilder translateYPercentage(float[] fractions, Float... translateYPercentage) {
        holder(fractions, Sprite.TRANSLATE_Y_PERCENTAGE, translateYPercentage);
        return this;
    }

    private void holder(float[] fractions, Property property, Float[] values) {
        ensurePair(fractions.length, values.length);
        fds.put(property.getName(), new FloatFrameData(fractions, property, values));
    }


    private void holder(float[] fractions, Property property, Integer[] values) {
        ensurePair(fractions.length, values.length);
        fds.put(property.getName(), new IntFrameData(fractions, property, values));
    }

    private void ensurePair(int fractionsLength, int valuesLength) {
        if (fractionsLength != valuesLength) {
            throw new IllegalStateException(String.format(
                    Locale.getDefault(),
                    "The fractions.length must equal values.length, " +
                            "fraction.length[%d], values.length[%d]",
                    fractionsLength,
                    valuesLength));
        }
    }


    public SpriteAnimatorBuilder interpolator(Interpolator interpolator) {
        this.interpolator = interpolator;
        return this;
    }

    public SpriteAnimatorBuilder easeInOut(float... fractions) {
        interpolator(KeyFrameInterpolator.easeInOut(
                fractions
        ));
        return this;
    }


    public SpriteAnimatorBuilder duration(long duration) {
        this.duration = duration;
        return this;
    }

    @SuppressWarnings("unused")
    public SpriteAnimatorBuilder repeatCount(int repeatCount) {
        this.repeatCount = repeatCount;
        return this;
    }

    public SpriteAnimatorBuilder startFrame(int startFrame) {
        if (startFrame < 0) {
            Log.w(TAG, "startFrame should always be non-negative");
            startFrame = 0;
        }
        this.startFrame = startFrame;
        return this;
    }

    public ObjectAnimator build() {

        PropertyValuesHolder[] holders = new PropertyValuesHolder[fds.size()];
        int i = 0;
        for (Map.Entry<String, FrameData> fd : fds.entrySet()) {
            FrameData data = fd.getValue();
            Keyframe[] keyframes = new Keyframe[data.fractions.length];
            float[] fractions = data.fractions;
            float startF = fractions[startFrame];
            for (int j = startFrame; j < (startFrame + data.values.length); j++) {
                int key = j - startFrame;
                int vk = j % data.values.length;
                float fraction = fractions[vk] - startF;
                if (fraction < 0) {
                    fraction = fractions[fractions.length - 1] + fraction;
                }
                if (data instanceof IntFrameData) {
                    keyframes[key] = Keyframe.ofInt(fraction, (Integer) data.values[vk]);
                } else if (data instanceof FloatFrameData) {
                    keyframes[key] = Keyframe.ofFloat(fraction, (Float) data.values[vk]);
                } else {
                    keyframes[key] = Keyframe.ofObject(fraction, data.values[vk]);
                }
            }
            holders[i] = PropertyValuesHolder.ofKeyframe(data.property, keyframes);
            i++;
        }

        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(sprite,
                holders);
        animator.setDuration(duration);
        animator.setRepeatCount(repeatCount);
        animator.setInterpolator(interpolator);
        return animator;
    }

}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/Ease.java
================================================
package com.github.ybq.android.spinkit.animation.interpolator;

import android.view.animation.Interpolator;

/**
 * Created by ybq.
 */
public class Ease {
    public static Interpolator inOut() {
        return PathInterpolatorCompat.create(0.42f, 0f, 0.58f, 1f);
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/KeyFrameInterpolator.java
================================================
package com.github.ybq.android.spinkit.animation.interpolator;

import android.animation.TimeInterpolator;
import android.view.animation.Interpolator;

/**
 * Created by ybq.
 */
public class KeyFrameInterpolator implements Interpolator {

    private TimeInterpolator interpolator;
    private float[] fractions;


    public static KeyFrameInterpolator easeInOut(float... fractions) {
        KeyFrameInterpolator interpolator = new KeyFrameInterpolator(Ease.inOut());
        interpolator.setFractions(fractions);
        return interpolator;
    }

    public static KeyFrameInterpolator pathInterpolator(float controlX1, float controlY1,
                                                        float controlX2, float controlY2,
                                                        float... fractions) {
        KeyFrameInterpolator interpolator = new KeyFrameInterpolator(PathInterpolatorCompat.create(controlX1, controlY1, controlX2, controlY2));
        interpolator.setFractions(fractions);
        return interpolator;
    }

    public KeyFrameInterpolator(TimeInterpolator interpolator, float... fractions) {
        this.interpolator = interpolator;
        this.fractions = fractions;
    }

    public void setFractions(float... fractions) {
        this.fractions = fractions;
    }

    @Override
    public float getInterpolation(float input) {
        if (fractions.length > 1) {
            for (int i = 0; i < fractions.length - 1; i++) {
                float start = fractions[i];
                float end = fractions[i + 1];
                float duration = end - start;
                if (input >= start && input <= end) {
                    input = (input - start) / duration;
                    return start + (interpolator.getInterpolation(input)
                            * duration);
                }
            }
        }
        return interpolator.getInterpolation(input);
    }
}

================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/PathInterpolatorCompat.java
================================================
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.github.ybq.android.spinkit.animation.interpolator;

import android.graphics.Path;
import android.os.Build;
import android.view.animation.Interpolator;

/**
 * Helper for creating path-based {@link Interpolator} instances. On API 21 or newer, the
 * platform implementation will be used and on older platforms a compatible alternative
 * implementation will be used.
 */
public class PathInterpolatorCompat {

    private PathInterpolatorCompat() {
        // prevent instantiation
    }

    /**
     * Create an {@link Interpolator} for an arbitrary {@link Path}. The {@link Path}
     * must begin at {@code (0, 0)} and end at {@code (1, 1)}. The x-coordinate along the
     * {@link Path} is the input value and the output is the y coordinate of the line at that
     * point. This means that the Path must conform to a function {@code y = f(x)}.
     * <p>
     * The {@link Path} must not have gaps in the x direction and must not
     * loop back on itself such that there can be two points sharing the same x coordinate.
     *
     * @param path the {@link Path} to use to make the line representing the {@link Interpolator}
     * @return the {@link Interpolator} representing the {@link Path}
     */
    @SuppressWarnings("unused")
    public static Interpolator create(Path path) {
        if (Build.VERSION.SDK_INT >= 21) {
            return PathInterpolatorCompatApi21.create(path);
        }
        return PathInterpolatorCompatBase.create(path);
    }

    /**
     * Create an {@link Interpolator} for a quadratic Bezier curve. The end points
     * {@code (0, 0)} and {@code (1, 1)} are assumed.
     *
     * @param controlX the x coordinate of the quadratic Bezier control point
     * @param controlY the y coordinate of the quadratic Bezier control point
     * @return the {@link Interpolator} representing the quadratic Bezier curve
     */
    @SuppressWarnings("unused")
    public static Interpolator create(float controlX, float controlY) {
        if (Build.VERSION.SDK_INT >= 21) {
            return PathInterpolatorCompatApi21.create(controlX, controlY);
        }
        return PathInterpolatorCompatBase.create(controlX, controlY);
    }

    /**
     * Create an {@link Interpolator} for a cubic Bezier curve.  The end points
     * {@code (0, 0)} and {@code (1, 1)} are assumed.
     *
     * @param controlX1 the x coordinate of the first control point of the cubic Bezier
     * @param controlY1 the y coordinate of the first control point of the cubic Bezier
     * @param controlX2 the x coordinate of the second control point of the cubic Bezier
     * @param controlY2 the y coordinate of the second control point of the cubic Bezier
     * @return the {@link Interpolator} representing the cubic Bezier curve
     */
    public static Interpolator create(float controlX1, float controlY1,
                                      float controlX2, float controlY2) {
        if (Build.VERSION.SDK_INT >= 21) {
            return PathInterpolatorCompatApi21.create(controlX1, controlY1, controlX2, controlY2);
        }
        return PathInterpolatorCompatBase.create(controlX1, controlY1, controlX2, controlY2);
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/PathInterpolatorCompatApi21.java
================================================
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.github.ybq.android.spinkit.animation.interpolator;

import android.annotation.TargetApi;
import android.graphics.Path;
import android.os.Build;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;

/**
 * API 21+ implementation for path interpolator compatibility.
 */
class PathInterpolatorCompatApi21 {

    private PathInterpolatorCompatApi21() {
        // prevent instantiation
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static Interpolator create(Path path) {
        return new PathInterpolator(path);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static Interpolator create(float controlX, float controlY) {
        return new PathInterpolator(controlX, controlY);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static Interpolator create(float controlX1, float controlY1,
                                      float controlX2, float controlY2) {
        return new PathInterpolator(controlX1, controlY1, controlX2, controlY2);
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/PathInterpolatorCompatBase.java
================================================
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.github.ybq.android.spinkit.animation.interpolator;

import android.graphics.Path;
import android.view.animation.Interpolator;

/**
 * Base implementation for path interpolator compatibility.
 */
class PathInterpolatorCompatBase {

    private PathInterpolatorCompatBase() {
        // prevent instantiation
    }

    public static Interpolator create(Path path) {
        return new PathInterpolatorDonut(path);
    }

    public static Interpolator create(float controlX, float controlY) {
        return new PathInterpolatorDonut(controlX, controlY);
    }

    public static Interpolator create(float controlX1, float controlY1,
                                      float controlX2, float controlY2) {
        return new PathInterpolatorDonut(controlX1, controlY1, controlX2, controlY2);
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/PathInterpolatorDonut.java
================================================
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.ybq.android.spinkit.animation.interpolator;

import android.graphics.Path;
import android.graphics.PathMeasure;
import android.view.animation.Interpolator;

/**
 * A path interpolator implementation compatible with API 4+.
 */
class PathInterpolatorDonut implements Interpolator {

    /**
     * Governs the accuracy of the approximation of the {@link Path}.
     */
    private static final float PRECISION = 0.002f;

    private final float[] mX;
    private final float[] mY;

    public PathInterpolatorDonut(Path path) {
        final PathMeasure pathMeasure = new PathMeasure(path, false /* forceClosed */);

        final float pathLength = pathMeasure.getLength();
        final int numPoints = (int) (pathLength / PRECISION) + 1;

        mX = new float[numPoints];
        mY = new float[numPoints];

        final float[] position = new float[2];
        for (int i = 0; i < numPoints; ++i) {
            final float distance = (i * pathLength) / (numPoints - 1);
            pathMeasure.getPosTan(distance, position, null /* tangent */);

            mX[i] = position[0];
            mY[i] = position[1];
        }
    }

    public PathInterpolatorDonut(float controlX, float controlY) {
        this(createQuad(controlX, controlY));
    }

    public PathInterpolatorDonut(float controlX1, float controlY1,
                                 float controlX2, float controlY2) {
        this(createCubic(controlX1, controlY1, controlX2, controlY2));
    }

    @Override
    public float getInterpolation(float t) {
        if (t <= 0.0f) {
            return 0.0f;
        } else if (t >= 1.0f) {
            return 1.0f;
        }

        // Do a binary search for the correct x to interpolate between.
        int startIndex = 0;
        int endIndex = mX.length - 1;
        while (endIndex - startIndex > 1) {
            int midIndex = (startIndex + endIndex) / 2;
            if (t < mX[midIndex]) {
                endIndex = midIndex;
            } else {
                startIndex = midIndex;
            }
        }

        final float xRange = mX[endIndex] - mX[startIndex];
        if (xRange == 0) {
            return mY[startIndex];
        }

        final float tInRange = t - mX[startIndex];
        final float fraction = tInRange / xRange;

        final float startY = mY[startIndex];
        final float endY = mY[endIndex];

        return startY + (fraction * (endY - startY));
    }

    private static Path createQuad(float controlX, float controlY) {
        final Path path = new Path();
        path.moveTo(0.0f, 0.0f);
        path.quadTo(controlX, controlY, 1.0f, 1.0f);
        return path;
    }

    private static Path createCubic(float controlX1, float controlY1,
                                    float controlX2, float controlY2) {
        final Path path = new Path();
        path.moveTo(0.0f, 0.0f);
        path.cubicTo(controlX1, controlY1, controlX2, controlY2, 1.0f, 1.0f);
        return path;
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/CircleLayoutContainer.java
================================================
package com.github.ybq.android.spinkit.sprite;

import android.graphics.Canvas;
import android.graphics.Rect;

/**
 * Created by ybq.
 */
public abstract class CircleLayoutContainer extends SpriteContainer {

    @Override
    public void drawChild(Canvas canvas) {
        for (int i = 0; i < getChildCount(); i++) {
            Sprite sprite = getChildAt(i);
            int count = canvas.save();
            canvas.rotate(i * 360 / getChildCount(),
                    getBounds().centerX(),
                    getBounds().centerY());
            sprite.draw(canvas);
            canvas.restoreToCount(count);
        }
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        bounds = clipSquare(bounds);
        int radius = (int) (bounds.width() * Math.PI / 3.6f / getChildCount());
        int left = bounds.centerX() - radius;
        int right = bounds.centerX() + radius;
        for (int i = 0; i < getChildCount(); i++) {
            Sprite sprite = getChildAt(i);
            sprite.setDrawBounds(left, bounds.top, right, bounds.top + radius * 2);
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/CircleSprite.java
================================================
package com.github.ybq.android.spinkit.sprite;

import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Paint;

/**
 * Created by ybq.
 */
public class CircleSprite extends ShapeSprite {

    @Override
    public ValueAnimator onCreateAnimation() {
        return null;
    }

    @Override
    public void drawShape(Canvas canvas, Paint paint) {
        if (getDrawBounds() != null) {
            int radius = Math.min(getDrawBounds().width(), getDrawBounds().height()) / 2;
            canvas.drawCircle(getDrawBounds().centerX(),
                    getDrawBounds().centerY(),
                    radius, paint);
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/RectSprite.java
================================================
package com.github.ybq.android.spinkit.sprite;

import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Paint;

/**
 * Created by ybq.
 */
public class RectSprite extends ShapeSprite {
    @Override
    public ValueAnimator onCreateAnimation() {
        return null;
    }

    @Override
    public void drawShape(Canvas canvas, Paint paint) {
        if (getDrawBounds() != null) {
            canvas.drawRect(getDrawBounds(), paint);
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/RingSprite.java
================================================
package com.github.ybq.android.spinkit.sprite;

import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Paint;

/**
 * Created by ybq.
 */
public class RingSprite extends ShapeSprite {


    @Override
    public void drawShape(Canvas canvas, Paint paint) {
        if (getDrawBounds() != null) {
            paint.setStyle(Paint.Style.STROKE);
            int radius = Math.min(getDrawBounds().width(), getDrawBounds().height()) / 2;
            paint.setStrokeWidth(radius / 12);
            canvas.drawCircle(getDrawBounds().centerX(),
                    getDrawBounds().centerY(),
                    radius, paint);
        }
    }

    @Override
    public ValueAnimator onCreateAnimation() {
        return null;
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/ShapeSprite.java
================================================
package com.github.ybq.android.spinkit.sprite;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;

/**
 * Created by ybq.
 */
public abstract class ShapeSprite extends Sprite {

    private Paint mPaint;
    private int mUseColor;
    private int mBaseColor;

    public ShapeSprite() {
        setColor(Color.WHITE);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(mUseColor);
    }

    @Override
    public void setColor(int color) {
        mBaseColor = color;
        updateUseColor();
    }

    @Override
    public int getColor() {
        return mBaseColor;
    }

    @SuppressWarnings("unused")
    public int getUseColor() {
        return mUseColor;
    }

    @Override
    public void setAlpha(int alpha) {
        super.setAlpha(alpha);
        updateUseColor();
    }

    private void updateUseColor() {
        int alpha = getAlpha();
        alpha += alpha >> 7;
        final int baseAlpha = mBaseColor >>> 24;
        final int useAlpha = baseAlpha * alpha >> 8;
        mUseColor = (mBaseColor << 8 >>> 8) | (useAlpha << 24);
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        mPaint.setColorFilter(colorFilter);
    }

    @Override
    protected final void drawSelf(Canvas canvas) {
        mPaint.setColor(mUseColor);
        drawShape(canvas, mPaint);
    }

    public abstract void drawShape(Canvas canvas, Paint paint);
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/Sprite.java
================================================
package com.github.ybq.android.spinkit.sprite;

import android.animation.ValueAnimator;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.util.Property;

import com.github.ybq.android.spinkit.animation.AnimationUtils;
import com.github.ybq.android.spinkit.animation.FloatProperty;
import com.github.ybq.android.spinkit.animation.IntProperty;

/**
 * Created by ybq.
 */
public abstract class Sprite extends Drawable implements
        ValueAnimator.AnimatorUpdateListener
        , Animatable
        , Drawable.Callback {

    private float scale = 1;
    private float scaleX = 1;
    private float scaleY = 1;
    private float pivotX;
    private float pivotY;
    private int animationDelay;
    private int rotateX;
    private int rotateY;
    private int translateX;
    private int translateY;
    private int rotate;
    private float translateXPercentage;
    private float translateYPercentage;
    private ValueAnimator animator;
    private int alpha = 255;
    private static final Rect ZERO_BOUNDS_RECT = new Rect();
    protected Rect drawBounds = ZERO_BOUNDS_RECT;
    private Camera mCamera;
    private Matrix mMatrix;

    public Sprite() {
        mCamera = new Camera();
        mMatrix = new Matrix();
    }

    public abstract int getColor();

    public abstract void setColor(int color);

    @Override
    public void setAlpha(int alpha) {
        this.alpha = alpha;
    }

    @Override
    public int getAlpha() {
        return alpha;
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    public float getTranslateXPercentage() {
        return translateXPercentage;
    }

    public void setTranslateXPercentage(float translateXPercentage) {
        this.translateXPercentage = translateXPercentage;
    }

    public float getTranslateYPercentage() {
        return translateYPercentage;
    }

    public void setTranslateYPercentage(float translateYPercentage) {
        this.translateYPercentage = translateYPercentage;
    }

    public int getTranslateX() {
        return translateX;
    }

    public void setTranslateX(int translateX) {
        this.translateX = translateX;
    }

    public int getTranslateY() {
        return translateY;
    }

    public void setTranslateY(int translateY) {
        this.translateY = translateY;
    }

    public int getRotate() {
        return rotate;
    }

    public void setRotate(int rotate) {
        this.rotate = rotate;
    }

    public float getScale() {
        return scale;
    }

    public void setScale(float scale) {
        this.scale = scale;
        setScaleX(scale);
        setScaleY(scale);
    }

    public float getScaleX() {
        return scaleX;
    }

    public void setScaleX(float scaleX) {
        this.scaleX = scaleX;
    }

    public float getScaleY() {
        return scaleY;
    }

    public void setScaleY(float scaleY) {
        this.scaleY = scaleY;
    }

    public int getRotateX() {
        return rotateX;
    }

    public void setRotateX(int rotateX) {
        this.rotateX = rotateX;
    }

    public int getRotateY() {
        return rotateY;
    }

    public void setRotateY(int rotateY) {
        this.rotateY = rotateY;
    }

    public float getPivotX() {
        return pivotX;
    }

    public void setPivotX(float pivotX) {
        this.pivotX = pivotX;
    }

    public float getPivotY() {
        return pivotY;
    }

    public void setPivotY(float pivotY) {
        this.pivotY = pivotY;
    }

    @SuppressWarnings("unused")
    public int getAnimationDelay() {
        return animationDelay;
    }

    public Sprite setAnimationDelay(int animationDelay) {
        this.animationDelay = animationDelay;
        return this;
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {

    }

    public abstract ValueAnimator onCreateAnimation();

    @Override
    public void start() {
        if (AnimationUtils.isStarted(animator)) {
            return;
        }

        animator = obtainAnimation();
        if (animator == null) {
            return;
        }

        AnimationUtils.start(animator);
        invalidateSelf();
    }

    public ValueAnimator obtainAnimation() {
        if (animator == null) {
            animator = onCreateAnimation();
        }
        if (animator != null) {
            animator.addUpdateListener(this);
            animator.setStartDelay(animationDelay);
        }
        return animator;
    }

    @Override
    public void stop() {
        if (AnimationUtils.isStarted(animator)) {
            animator.removeAllUpdateListeners();
            animator.end();
            reset();
        }
    }

    protected abstract void drawSelf(Canvas canvas);

    public void reset() {
        scale = 1;
        rotateX = 0;
        rotateY = 0;
        translateX = 0;
        translateY = 0;
        rotate = 0;
        translateXPercentage = 0f;
        translateYPercentage = 0f;
    }

    @Override
    public boolean isRunning() {
        return AnimationUtils.isRunning(animator);
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        setDrawBounds(bounds);
    }

    public void setDrawBounds(Rect drawBounds) {
        setDrawBounds(drawBounds.left, drawBounds.top, drawBounds.right, drawBounds.bottom);
    }

    public void setDrawBounds(int left, int top, int right, int bottom) {
        this.drawBounds = new Rect(left, top, right, bottom);
        setPivotX(getDrawBounds().centerX());
        setPivotY(getDrawBounds().centerY());
    }

    @Override
    public void invalidateDrawable(Drawable who) {
        invalidateSelf();
    }

    @Override
    public void scheduleDrawable(Drawable who, Runnable what, long when) {

    }

    @Override
    public void unscheduleDrawable(Drawable who, Runnable what) {

    }

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        final Callback callback = getCallback();
        if (callback != null) {
            callback.invalidateDrawable(this);
        }
    }

    public Rect getDrawBounds() {
        return drawBounds;
    }

    @Override
    public void draw(Canvas canvas) {
        int tx = getTranslateX();
        tx = tx == 0 ? (int) (getBounds().width() * getTranslateXPercentage()) : tx;
        int ty = getTranslateY();
        ty = ty == 0 ? (int) (getBounds().height() * getTranslateYPercentage()) : ty;
        canvas.translate(tx, ty);
        canvas.scale(getScaleX(), getScaleY(), getPivotX(), getPivotY());
        canvas.rotate(getRotate(), getPivotX(), getPivotY());

        if (getRotateX() != 0 || getRotateY() != 0) {
            mCamera.save();
            mCamera.rotateX(getRotateX());
            mCamera.rotateY(getRotateY());
            mCamera.getMatrix(mMatrix);
            mMatrix.preTranslate(-getPivotX(), -getPivotY());
            mMatrix.postTranslate(getPivotX(), getPivotY());
            mCamera.restore();
            canvas.concat(mMatrix);
        }
        drawSelf(canvas);
    }

    public Rect clipSquare(Rect rect) {
        int w = rect.width();
        int h = rect.height();
        int min = Math.min(w, h);
        int cx = rect.centerX();
        int cy = rect.centerY();
        int r = min / 2;
        return new Rect(
                cx - r,
                cy - r,
                cx + r,
                cy + r
        );
    }

    public static final Property<Sprite, Integer> ROTATE_X = new IntProperty<Sprite>("rotateX") {
        @Override
        public void setValue(Sprite object, int value) {
            object.setRotateX(value);
        }

        @Override
        public Integer get(Sprite object) {
            return object.getRotateX();
        }
    };

    public static final Property<Sprite, Integer> ROTATE = new IntProperty<Sprite>("rotate") {
        @Override
        public void setValue(Sprite object, int value) {
            object.setRotate(value);
        }

        @Override
        public Integer get(Sprite object) {
            return object.getRotate();
        }
    };

    public static final Property<Sprite, Integer> ROTATE_Y = new IntProperty<Sprite>("rotateY") {
        @Override
        public void setValue(Sprite object, int value) {
            object.setRotateY(value);
        }

        @Override
        public Integer get(Sprite object) {
            return object.getRotateY();
        }
    };

    @SuppressWarnings("unused")
    public static final Property<Sprite, Integer> TRANSLATE_X = new IntProperty<Sprite>("translateX") {
        @Override
        public void setValue(Sprite object, int value) {
            object.setTranslateX(value);
        }

        @Override
        public Integer get(Sprite object) {
            return object.getTranslateX();
        }
    };

    @SuppressWarnings("unused")
    public static final Property<Sprite, Integer> TRANSLATE_Y = new IntProperty<Sprite>("translateY") {
        @Override
        public void setValue(Sprite object, int value) {
            object.setTranslateY(value);
        }

        @Override
        public Integer get(Sprite object) {
            return object.getTranslateY();
        }
    };

    public static final Property<Sprite, Float> TRANSLATE_X_PERCENTAGE = new FloatProperty<Sprite>("translateXPercentage") {
        @Override
        public void setValue(Sprite object, float value) {
            object.setTranslateXPercentage(value);
        }

        @Override
        public Float get(Sprite object) {
            return object.getTranslateXPercentage();
        }
    };

    public static final Property<Sprite, Float> TRANSLATE_Y_PERCENTAGE = new FloatProperty<Sprite>("translateYPercentage") {
        @Override
        public void setValue(Sprite object, float value) {
            object.setTranslateYPercentage(value);
        }

        @Override
        public Float get(Sprite object) {
            return object.getTranslateYPercentage();
        }
    };

    @SuppressWarnings("unused")
    public static final Property<Sprite, Float> SCALE_X = new FloatProperty<Sprite>("scaleX") {
        @Override
        public void setValue(Sprite object, float value) {
            object.setScaleX(value);
        }

        @Override
        public Float get(Sprite object) {
            return object.getScaleX();
        }
    };

    public static final Property<Sprite, Float> SCALE_Y = new FloatProperty<Sprite>("scaleY") {
        @Override
        public void setValue(Sprite object, float value) {
            object.setScaleY(value);
        }

        @Override
        public Float get(Sprite object) {
            return object.getScaleY();
        }
    };

    public static final Property<Sprite, Float> SCALE = new FloatProperty<Sprite>("scale") {
        @Override
        public void setValue(Sprite object, float value) {
            object.setScale(value);
        }

        @Override
        public Float get(Sprite object) {
            return object.getScale();
        }
    };

    public static final Property<Sprite, Integer> ALPHA = new IntProperty<Sprite>("alpha") {
        @Override
        public void setValue(Sprite object, int value) {
            object.setAlpha(value);
        }

        @Override
        public Integer get(Sprite object) {
            return object.getAlpha();
        }
    };

}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/SpriteContainer.java
================================================
package com.github.ybq.android.spinkit.sprite;

import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Rect;

import com.github.ybq.android.spinkit.animation.AnimationUtils;

/**
 * Created by ybq.
 */
public abstract class SpriteContainer extends Sprite {

    private Sprite[] sprites;

    private int color;

    public SpriteContainer() {
        sprites = onCreateChild();
        initCallBack();
        onChildCreated(sprites);
    }

    private void initCallBack() {
        if (sprites != null) {
            for (Sprite sprite : sprites) {
                sprite.setCallback(this);
            }
        }
    }

    public void onChildCreated(Sprite... sprites) {

    }

    public int getChildCount() {
        return sprites == null ? 0 : sprites.length;
    }

    public Sprite getChildAt(int index) {
        return sprites == null ? null : sprites[index];
    }

    @Override
    public void setColor(int color) {
        this.color = color;
        for (int i = 0; i < getChildCount(); i++) {
            getChildAt(i).setColor(color);
        }
    }

    @Override
    public int getColor() {
        return color;
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        drawChild(canvas);
    }

    public void drawChild(Canvas canvas) {
        if (sprites != null) {
            for (Sprite sprite : sprites) {
                int count = canvas.save();
                sprite.draw(canvas);
                canvas.restoreToCount(count);
            }
        }
    }

    @Override
    protected void drawSelf(Canvas canvas) {
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        for (Sprite sprite : sprites) {
            sprite.setBounds(bounds);
        }
    }

    @Override
    public void start() {
        super.start();
        AnimationUtils.start(sprites);
    }

    @Override
    public void stop() {
        super.stop();
        AnimationUtils.stop(sprites);
    }

    @Override
    public boolean isRunning() {
        return AnimationUtils.isRunning(sprites) || super.isRunning();
    }

    public abstract Sprite[] onCreateChild();

    @Override
    public ValueAnimator onCreateAnimation() {
        return null;
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/ChasingDots.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;
import android.graphics.Rect;
import android.os.Build;
import android.view.animation.LinearInterpolator;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.sprite.CircleSprite;
import com.github.ybq.android.spinkit.sprite.Sprite;
import com.github.ybq.android.spinkit.sprite.SpriteContainer;

/**
 * Created by ybq.
 */
public class ChasingDots extends SpriteContainer {

    @Override
    public Sprite[] onCreateChild() {
        return new Sprite[]{
                new Dot(),
                new Dot()
        };
    }

    @Override
    public void onChildCreated(Sprite... sprites) {
        super.onChildCreated(sprites);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            sprites[1].setAnimationDelay(1000);
        } else {
            sprites[1].setAnimationDelay(-1000);
        }
    }

    @Override
    public ValueAnimator onCreateAnimation() {
        float fractions[] = new float[]{0f, 1f};
        return new SpriteAnimatorBuilder(this).
                rotate(fractions, 0, 360).
                duration(2000).
                interpolator(new LinearInterpolator()).
                build();
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        bounds = clipSquare(bounds);
        int drawW = (int) (bounds.width() * 0.6f);
        getChildAt(0).setDrawBounds(
                bounds.right - drawW,
                bounds.top,
                bounds.right
                , bounds.top + drawW
        );
        getChildAt(1).setDrawBounds(
                bounds.right - drawW,
                bounds.bottom - drawW,
                bounds.right,
                bounds.bottom
        );
    }

    private class Dot extends CircleSprite {

        Dot() {
            setScale(0f);
        }

        @Override
        public ValueAnimator onCreateAnimation() {
            float fractions[] = new float[]{0f, 0.5f, 1f};
            return new SpriteAnimatorBuilder(this).
                    scale(fractions, 0f, 1f, 0f).
                    duration(2000).
                    easeInOut(fractions)
                    .build();
        }
    }

}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/Circle.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;
import android.os.Build;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.sprite.CircleLayoutContainer;
import com.github.ybq.android.spinkit.sprite.CircleSprite;
import com.github.ybq.android.spinkit.sprite.Sprite;

/**
 * Created by ybq.
 */
public class Circle extends CircleLayoutContainer {

    @Override
    public Sprite[] onCreateChild() {
        Dot[] dots = new Dot[12];
        for (int i = 0; i < dots.length; i++) {
            dots[i] = new Dot();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                dots[i].setAnimationDelay(1200 / 12 * i);
            } else {
                dots[i].setAnimationDelay(1200 / 12 * i + -1200);
            }
        }
        return dots;
    }

    private class Dot extends CircleSprite {

        Dot() {
            setScale(0f);
        }

        @Override
        public ValueAnimator onCreateAnimation() {
            float fractions[] = new float[]{0f, 0.5f, 1f};
            return new SpriteAnimatorBuilder(this).
                    scale(fractions, 0f, 1f, 0f).
                    duration(1200).
                    easeInOut(fractions)
                    .build();
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/CubeGrid.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;
import android.graphics.Rect;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.sprite.RectSprite;
import com.github.ybq.android.spinkit.sprite.Sprite;
import com.github.ybq.android.spinkit.sprite.SpriteContainer;

/**
 * Created by ybq.
 */
public class CubeGrid extends SpriteContainer {

    @Override
    public Sprite[] onCreateChild() {
        int delays[] = new int[]{
                200, 300, 400
                , 100, 200, 300
                , 0, 100, 200
        };
        GridItem[] gridItems = new GridItem[9];
        for (int i = 0; i < gridItems.length; i++) {
            gridItems[i] = new GridItem();
            gridItems[i].setAnimationDelay(delays[i]);
        }
        return gridItems;
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        bounds = clipSquare(bounds);
        int width = (int) (bounds.width() * 0.33f);
        int height = (int) (bounds.height() * 0.33f);
        for (int i = 0; i < getChildCount(); i++) {
            int x = i % 3;
            int y = i / 3;
            int l = bounds.left + x * width;
            int t = bounds.top + y * height;
            Sprite sprite = getChildAt(i);
            sprite.setDrawBounds(l, t, l + width, t + height);
        }
    }

    private class GridItem extends RectSprite {
        @Override
        public ValueAnimator onCreateAnimation() {
            float fractions[] = new float[]{0f, 0.35f, 0.7f, 1f};
            return new SpriteAnimatorBuilder(this).
                    scale(fractions, 1f, 0f, 1f, 1f).
                    duration(1300).
                    easeInOut(fractions)
                    .build();
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/DoubleBounce.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;
import android.os.Build;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.sprite.CircleSprite;
import com.github.ybq.android.spinkit.sprite.Sprite;
import com.github.ybq.android.spinkit.sprite.SpriteContainer;

/**
 * Created by ybq.
 */
public class DoubleBounce extends SpriteContainer {

    @Override
    public Sprite[] onCreateChild() {
        return new Sprite[]{
                new Bounce(), new Bounce()
        };
    }

    @Override
    public void onChildCreated(Sprite... sprites) {
        super.onChildCreated(sprites);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            sprites[1].setAnimationDelay(1000);
        } else {
            sprites[1].setAnimationDelay(-1000);
        }
    }

    private class Bounce extends CircleSprite {

        Bounce() {
            setAlpha(153);
            setScale(0f);
        }

        @Override
        public ValueAnimator onCreateAnimation() {
            float fractions[] = new float[]{0f, 0.5f, 1f};
            return new SpriteAnimatorBuilder(this).scale(fractions, 0f, 1f, 0f).
                    duration(2000).
                    easeInOut(fractions)
                    .build();
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/FadingCircle.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;
import android.os.Build;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.sprite.CircleLayoutContainer;
import com.github.ybq.android.spinkit.sprite.CircleSprite;
import com.github.ybq.android.spinkit.sprite.Sprite;

/**
 * Created by ybq.
 */
public class FadingCircle extends CircleLayoutContainer {

    @Override
    public Sprite[] onCreateChild() {
        Dot[] dots = new Dot[12];
        for (int i = 0; i < dots.length; i++) {
            dots[i] = new Dot();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                dots[i].setAnimationDelay(1200 / 12 * i);
            } else {
                dots[i].setAnimationDelay(1200 / 12 * i + -1200);
            }
        }
        return dots;
    }

    private class Dot extends CircleSprite {

        Dot() {
            setAlpha(0);
        }

        @Override
        public ValueAnimator onCreateAnimation() {
            float fractions[] = new float[]{0f, 0.39f, 0.4f, 1f};
            return new SpriteAnimatorBuilder(this).
                    alpha(fractions, 0, 0, 255, 0).
                    duration(1200).
                    easeInOut(fractions).build();
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/FoldingCube.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.Build;
import android.view.animation.LinearInterpolator;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.sprite.RectSprite;
import com.github.ybq.android.spinkit.sprite.Sprite;
import com.github.ybq.android.spinkit.sprite.SpriteContainer;

/**
 * Created by ybq.
 */
public class FoldingCube extends SpriteContainer {

    @SuppressWarnings("FieldCanBeLocal")
    private boolean wrapContent = false;

    @Override
    public Sprite[] onCreateChild() {
        Cube[] cubes
                = new Cube[4];
        for (int i = 0; i < cubes.length; i++) {
            cubes[i] = new Cube();

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                cubes[i].setAnimationDelay(300 * i);
            } else {
                cubes[i].setAnimationDelay(300 * i - 1200);
            }
        }
        return cubes;
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        bounds = clipSquare(bounds);
        int size = Math.min(bounds.width(), bounds.height());
        if (wrapContent) {
            size = (int) Math.sqrt(
                    (size
                            * size) / 2);
            int oW = (bounds.width() - size) / 2;
            int oH = (bounds.height() - size) / 2;
            bounds = new Rect(
                    bounds.left + oW,
                    bounds.top + oH,
                    bounds.right - oW,
                    bounds.bottom - oH
            );
        }

        int px = bounds.left + size / 2 + 1;
        int py = bounds.top + size / 2 + 1;
        for (int i = 0; i < getChildCount(); i++) {
            Sprite sprite = getChildAt(i);
            sprite.setDrawBounds(
                    bounds.left,
                    bounds.top,
                    px,
                    py
            );
            sprite.setPivotX(sprite.getDrawBounds().right);
            sprite.setPivotY(sprite.getDrawBounds().bottom);
        }
    }

    @Override
    public void drawChild(Canvas canvas) {

        Rect bounds = clipSquare(getBounds());
        for (int i = 0; i < getChildCount(); i++) {
            int count = canvas.save();
            canvas.rotate(45 + i * 90, bounds.centerX(), bounds.centerY());
            Sprite sprite = getChildAt(i);
            sprite.draw(canvas);
            canvas.restoreToCount(count);
        }
    }

    private class Cube extends RectSprite {

        Cube() {
            setAlpha(0);
            setRotateX(-180);
        }

        @Override
        public ValueAnimator onCreateAnimation() {
            float fractions[] = new float[]{0f, 0.1f, 0.25f, 0.75f, 0.9f, 1f};
            return new SpriteAnimatorBuilder(this).
                    alpha(fractions, 0, 0, 255, 255, 0, 0).
                    rotateX(fractions, -180, -180, 0, 0, 0, 0).
                    rotateY(fractions, 0, 0, 0, 0, 180, 180).
                    duration(2400).
                    interpolator(new LinearInterpolator())
                    .build();
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/MultiplePulse.java
================================================
package com.github.ybq.android.spinkit.style;

import com.github.ybq.android.spinkit.sprite.Sprite;
import com.github.ybq.android.spinkit.sprite.SpriteContainer;

/**
 * Created by ybq.
 */
public class MultiplePulse extends SpriteContainer {
    @Override
    public Sprite[] onCreateChild() {
        return new Sprite[]{
                new Pulse(),
                new Pulse(),
                new Pulse(),
        };
    }

    @Override
    public void onChildCreated(Sprite... sprites) {
        for (int i = 0; i < sprites.length; i++) {
            sprites[i].setAnimationDelay(200 * (i + 1));
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/MultiplePulseRing.java
================================================
package com.github.ybq.android.spinkit.style;

import com.github.ybq.android.spinkit.sprite.Sprite;
import com.github.ybq.android.spinkit.sprite.SpriteContainer;

/**
 * Created by ybq.
 */
public class MultiplePulseRing extends SpriteContainer {

    @Override
    public Sprite[] onCreateChild() {
        return new Sprite[]{
                new PulseRing(),
                new PulseRing(),
                new PulseRing(),
        };
    }

    @Override
    public void onChildCreated(Sprite... sprites) {
        for (int i = 0; i < sprites.length; i++) {
            sprites[i].setAnimationDelay(200 * (i + 1));
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/Pulse.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.sprite.CircleSprite;

/**
 * Created by ybq.
 */
public class Pulse extends CircleSprite {

    public Pulse() {
        setScale(0f);
    }

    @Override
    public ValueAnimator onCreateAnimation() {
        float fractions[] = new float[]{0f, 1f};
        return new SpriteAnimatorBuilder(this).
                scale(fractions, 0f, 1f).
                alpha(fractions, 255, 0).
                duration(1000).
                easeInOut(fractions)
                .build();
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/PulseRing.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.animation.interpolator.KeyFrameInterpolator;
import com.github.ybq.android.spinkit.sprite.RingSprite;

/**
 * Created by ybq.
 */
public class PulseRing extends RingSprite {

    public PulseRing() {
        setScale(0f);
    }

    @Override
    public ValueAnimator onCreateAnimation() {
        float fractions[] = new float[]{0f, 0.7f, 1f};
        return new SpriteAnimatorBuilder(this).
                scale(fractions, 0f, 1f, 1f).
                alpha(fractions, 255, (int) (255 * 0.7), 0).
                duration(1000).
                interpolator(KeyFrameInterpolator.pathInterpolator(0.21f, 0.53f, 0.56f, 0.8f, fractions)).
                build();
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/RotatingCircle.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.sprite.CircleSprite;

public class RotatingCircle extends CircleSprite {

    @Override
    public ValueAnimator onCreateAnimation() {
        float fractions[] = new float[]{0f, 0.5f, 1f};
        return new SpriteAnimatorBuilder(this).
                rotateX(fractions, 0, -180, -180).
                rotateY(fractions, 0, 0, -180).
                duration(1200).
                easeInOut(fractions)
                .build();
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/RotatingPlane.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;
import android.graphics.Rect;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.sprite.RectSprite;

/**
 * Created by ybq.
 */
public class RotatingPlane extends RectSprite {
    @Override
    protected void onBoundsChange(Rect bounds) {
        setDrawBounds(clipSquare(bounds));
    }

    @Override
    public ValueAnimator onCreateAnimation() {
        float fractions[] = new float[]{0f, 0.5f, 1f};
        return new SpriteAnimatorBuilder(this).
                rotateX(fractions, 0, -180, -180).
                rotateY(fractions, 0, 0, -180).
                duration(1200).
                easeInOut(fractions)
                .build();
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/ThreeBounce.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;
import android.graphics.Rect;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.sprite.CircleSprite;
import com.github.ybq.android.spinkit.sprite.Sprite;
import com.github.ybq.android.spinkit.sprite.SpriteContainer;

/**
 * Created by ybq.
 */
public class ThreeBounce extends SpriteContainer {

    @Override
    public Sprite[] onCreateChild() {
        return new Sprite[]{
                new Bounce(),
                new Bounce(),
                new Bounce()
        };
    }

    @Override
    public void onChildCreated(Sprite... sprites) {
        super.onChildCreated(sprites);
        sprites[1].setAnimationDelay(160);
        sprites[2].setAnimationDelay(320);
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        bounds = clipSquare(bounds);
        int radius = bounds.width() / 8;
        int top = bounds.centerY() - radius;
        int bottom = bounds.centerY() + radius;

        for (int i = 0; i < getChildCount(); i++) {
            int left = bounds.width() * i / 3
                    + bounds.left;
            getChildAt(i).setDrawBounds(
                    left, top, left + radius * 2, bottom
            );
        }
    }

    private class Bounce extends CircleSprite {

        Bounce() {
            setScale(0f);
        }

        @Override
        public ValueAnimator onCreateAnimation() {
            float fractions[] = new float[]{0f, 0.4f, 0.8f, 1f};
            return new SpriteAnimatorBuilder(this).scale(fractions, 0f, 1f, 0f, 0f).
                    duration(1400).
                    easeInOut(fractions)
                    .build();
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/WanderingCubes.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;
import android.graphics.Rect;
import android.os.Build;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.sprite.RectSprite;
import com.github.ybq.android.spinkit.sprite.Sprite;
import com.github.ybq.android.spinkit.sprite.SpriteContainer;

/**
 * Created by ybq.
 */
public class WanderingCubes extends SpriteContainer {

    @Override
    public Sprite[] onCreateChild() {
        return new Sprite[]{
                new Cube(0),
                new Cube(3)
        };
    }

    @Override
    public void onChildCreated(Sprite... sprites) {
        super.onChildCreated(sprites);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            sprites[1].setAnimationDelay(-900);
        }
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        bounds = clipSquare(bounds);
        super.onBoundsChange(bounds);
        for (int i = 0; i < getChildCount(); i++) {
            Sprite sprite = getChildAt(i);
            sprite.setDrawBounds(
                    bounds.left,
                    bounds.top,
                    bounds.left + bounds.width() / 4,
                    bounds.top + bounds.height() / 4
            );
        }
    }

    private class Cube extends RectSprite {
        int startFrame;

        public Cube(int startFrame) {
            this.startFrame = startFrame;
        }

        @Override
        public ValueAnimator onCreateAnimation() {
            float fractions[] = new float[]{0f, 0.25f, 0.5f, 0.51f, 0.75f, 1f};
            SpriteAnimatorBuilder builder = new SpriteAnimatorBuilder(this).
                    rotate(fractions, 0, -90, -179, -180, -270, -360).
                    translateXPercentage(fractions, 0f, 0.75f, 0.75f, 0.75f, 0f, 0f).
                    translateYPercentage(fractions, 0f, 0f, 0.75f, 0.75f, 0.75f, 0f).
                    scale(fractions, 1f, 0.5f, 1f, 1f, 0.5f, 1f).
                    duration(1800).
                    easeInOut(fractions);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                builder.
                        startFrame(startFrame);
            }
            return builder.build();
        }
    }
}


================================================
FILE: library/src/main/java/com/github/ybq/android/spinkit/style/Wave.java
================================================
package com.github.ybq.android.spinkit.style;

import android.animation.ValueAnimator;
import android.graphics.Rect;
import android.os.Build;

import com.github.ybq.android.spinkit.animation.SpriteAnimatorBuilder;
import com.github.ybq.android.spinkit.sprite.RectSprite;
import com.github.ybq.android.spinkit.sprite.Sprite;
import com.github.ybq.android.spinkit.sprite.SpriteContainer;

/**
 * Created by ybq.
 */
public class Wave extends SpriteContainer {

    @Override
    public Sprite[] onCreateChild() {
        WaveItem[] waveItems = new WaveItem[5];
        for (int i = 0; i < waveItems.length; i++) {
            waveItems[i] = new WaveItem();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                waveItems[i].setAnimationDelay(600 + i * 100);
            } else {
                waveItems[i].setAnimationDelay(-1200 + i * 100);
            }

        }
        return waveItems;
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        bounds = clipSquare(bounds);
        int rw = bounds.width() / getChildCount();
        int width = bounds.width() / 5 * 3 / 5;
        for (int i = 0; i < getChildCount(); i++) {
            Sprite sprite = getChildAt(i);
            int l = bounds.left + i * rw + rw / 5;
            int r = l + width;
            sprite.setDrawBounds(l, bounds.top, r, bounds.bottom);
        }
    }

    private class WaveItem extends RectSprite {

        WaveItem() {
            setScaleY(0.4f);
        }

        @Override
        public ValueAnimator onCreateAnimation() {
            float fractions[] = new float[]{0f, 0.2f, 0.4f, 1f};
            return new SpriteAnimatorBuilder(this).scaleY(fractions, 0.4f, 1f, 0.4f, 0.4f).
                    duration(1200).
                    easeInOut(fractions)
                    .build();
        }
    }
}


================================================
FILE: library/src/main/res/values/attrs.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="SpinKitViewStyle" format="reference" />

    <declare-styleable name="SpinKitView">
        <attr name="SpinKit_Style">
            <enum name="RotatingPlane" value="0" />
            <enum name="DoubleBounce" value="1" />
            <enum name="Wave" value="2" />
            <enum name="WanderingCubes" value="3" />
            <enum name="Pulse" value="4" />
            <enum name="ChasingDots" value="5" />
            <enum name="ThreeBounce" value="6" />
            <enum name="Circle" value="7" />
            <enum name="CubeGrid" value="8" />
            <enum name="FadingCircle" value="9" />
            <enum name="FoldingCube" value="10" />
            <enum name="RotatingCircle" value="11" />
            <enum name="MultiplePulse" value="12" />
            <enum name="PulseRing" value="13" />
            <enum name="MultiplePulseRing" value="14" />
        </attr>
        <attr name="SpinKit_Color" format="color" />
    </declare-styleable>

</resources>

================================================
FILE: library/src/main/res/values/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="SpinKitView">
        <item name="android:indeterminateOnly">true</item>
        <item name="android:minWidth">48dip</item>
        <item name="android:maxWidth">48dip</item>
        <item name="android:minHeight">48dip</item>
        <item name="android:maxHeight">48dip</item>
    </style>

    <style name="SpinKitView.ChasingDots">
        <item name="SpinKit_Style">ChasingDots</item>
    </style>

    <style name="SpinKitView.Circle">
        <item name="SpinKit_Style">Circle</item>
    </style>

    <style name="SpinKitView.CubeGrid">
        <item name="SpinKit_Style">CubeGrid</item>
    </style>

    <style name="SpinKitView.DoubleBounce">
        <item name="SpinKit_Style">DoubleBounce</item>
    </style>

    <style name="SpinKitView.FadingCircle">
        <item name="SpinKit_Style">FadingCircle</item>
    </style>

    <style name="SpinKitView.FoldingCube">
        <item name="SpinKit_Style">FoldingCube</item>
    </style>

    <style name="SpinKitView.Pulse">
        <item name="SpinKit_Style">Pulse</item>
    </style>

    <style name="SpinKitView.RotatingPlane">
        <item name="SpinKit_Style">RotatingPlane</item>
    </style>

    <style name="SpinKitView.RotatingCircle">
        <item name="SpinKit_Style">RotatingCircle</item>
    </style>

    <style name="SpinKitView.ThreeBounce">
        <item name="SpinKit_Style">ThreeBounce</item>
    </style>

    <style name="SpinKitView.WanderingCubes">
        <item name="SpinKit_Style">WanderingCubes</item>
    </style>

    <style name="SpinKitView.Wave">
        <item name="SpinKit_Style">Wave</item>
    </style>

    <style name="SpinKitView.MultiplePulse">
        <item name="SpinKit_Style">MultiplePulse</item>
    </style>

    <style name="SpinKitView.PulseRing">
        <item name="SpinKit_Style">PulseRing</item>
    </style>

    <style name="SpinKitView.MultiplePulseRing">
        <item name="SpinKit_Style">MultiplePulseRing</item>
    </style>

    <style name="SpinKitView.Large">
        <item name="android:minWidth">76dip</item>
        <item name="android:maxWidth">76dip</item>
        <item name="android:minHeight">76dip</item>
        <item name="android:maxHeight">76dip</item>
    </style>

    <style name="SpinKitView.Large.ChasingDots">
        <item name="SpinKit_Style">ChasingDots</item>
    </style>

    <style name="SpinKitView.Large.Circle">
        <item name="SpinKit_Style">Circle</item>
    </style>

    <style name="SpinKitView.Large.CubeGrid">
        <item name="SpinKit_Style">CubeGrid</item>
    </style>

    <style name="SpinKitView.Large.DoubleBounce">
        <item name="SpinKit_Style">DoubleBounce</item>
    </style>

    <style name="SpinKitView.Large.FadingCircle">
        <item name="SpinKit_Style">FadingCircle</item>
    </style>

    <style name="SpinKitView.Large.FoldingCube">
        <item name="SpinKit_Style">FoldingCube</item>
    </style>

    <style name="SpinKitView.Large.Pulse">
        <item name="SpinKit_Style">Pulse</item>
    </style>

    <style name="SpinKitView.Large.RotatingPlane">
        <item name="SpinKit_Style">RotatingPlane</item>
    </style>

    <style name="SpinKitView.Large.RotatingCircle">
        <item name="SpinKit_Style">RotatingCircle</item>
    </style>

    <style name="SpinKitView.Large.ThreeBounce">
        <item name="SpinKit_Style">ThreeBounce</item>
    </style>

    <style name="SpinKitView.Large.WanderingCubes">
        <item name="SpinKit_Style">WanderingCubes</item>
    </style>

    <style name="SpinKitView.Large.Wave">
        <item name="SpinKit_Style">Wave</item>
    </style>

    <style name="SpinKitView.Large.MultiplePulse">
        <item name="SpinKit_Style">MultiplePulse</item>
    </style>

    <style name="SpinKitView.Large.PulseRing">
        <item name="SpinKit_Style">PulseRing</item>
    </style>

    <style name="SpinKitView.Large.MultiplePulseRing">
        <item name="SpinKit_Style">MultiplePulseRing</item>
    </style>

    <style name="SpinKitView.Small">
        <item name="android:minWidth">16dip</item>
        <item name="android:maxWidth">16dip</item>
        <item name="android:minHeight">16dip</item>
        <item name="android:maxHeight">16dip</item>
    </style>

    <style name="SpinKitView.Small.ChasingDots">
        <item name="SpinKit_Style">ChasingDots</item>
    </style>

    <style name="SpinKitView.Small.Circle">
        <item name="SpinKit_Style">Circle</item>
    </style>

    <style name="SpinKitView.Small.CubeGrid">
        <item name="SpinKit_Style">CubeGrid</item>
    </style>

    <style name="SpinKitView.Small.DoubleBounce">
        <item name="SpinKit_Style">DoubleBounce</item>
    </style>

    <style name="SpinKitView.Small.FadingCircle">
        <item name="SpinKit_Style">FadingCircle</item>
    </style>

    <style name="SpinKitView.Small.FoldingCube">
        <item name="SpinKit_Style">FoldingCube</item>
    </style>

    <style name="SpinKitView.Small.Pulse">
        <item name="SpinKit_Style">Pulse</item>
    </style>

    <style name="SpinKitView.Small.RotatingPlane">
        <item name="SpinKit_Style">RotatingPlane</item>
    </style>

    <style name="SpinKitView.Small.RotatingCircle">
        <item name="SpinKit_Style">RotatingCircle</item>
    </style>

    <style name="SpinKitView.Small.ThreeBounce">
        <item name="SpinKit_Style">ThreeBounce</item>
    </style>

    <style name="SpinKitView.Small.WanderingCubes">
        <item name="SpinKit_Style">WanderingCubes</item>
    </style>

    <style name="SpinKitView.Small.Wave">
        <item name="SpinKit_Style">Wave</item>
    </style>

    <style name="SpinKitView.Small.MultiplePulse">
        <item name="SpinKit_Style">MultiplePulse</item>
    </style>

    <style name="SpinKitView.Small.PulseRing">
        <item name="SpinKit_Style">PulseRing</item>
    </style>

    <style name="SpinKitView.Small.MultiplePulseRing">
        <item name="SpinKit_Style">MultiplePulseRing</item>
    </style>
</resources>

================================================
FILE: sample/.gitignore
================================================
/build


================================================
FILE: sample/build.gradle
================================================
apply plugin: 'com.android.application'

android {

    compileSdkVersion 28
    buildToolsVersion '28.0.3'

    defaultConfig {
        applicationId "com.github.ybq.android.spinkit"
        minSdkVersion 14
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.0.0'
    implementation 'com.google.android.material:material:1.0.0'
    implementation project(':library')
}


================================================
FILE: sample/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/ybq/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: sample/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.github.ybq.android.loading">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:testOnly="false"
        android:theme="@style/AppTheme">
        <activity
            android:name="com.github.ybq.android.loading.MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.github.ybq.android.loading.DetailActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar" />
    </application>

</manifest>


================================================
FILE: sample/src/main/java/com/github/ybq/android/loading/ArgbEvaluator.java
================================================

/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.github.ybq.android.loading;

import android.animation.TypeEvaluator;

/**
 * This evaluator can be used to perform type interpolation between integer
 * values that represent ARGB colors.
 */
public class ArgbEvaluator implements TypeEvaluator {
    private static final ArgbEvaluator sInstance = new ArgbEvaluator();

    /**
     * Returns an instance of <code>ArgbEvaluator</code> that may be used in
     * {@link android.animation.ValueAnimator#setEvaluator(TypeEvaluator)}. The same instance may
     * be used in multiple <code>Animator</code>s because it holds no state.
     *
     * @return An instance of <code>ArgbEvalutor</code>.
     */
    public static ArgbEvaluator getInstance() {
        return sInstance;
    }

    /**
     * This function returns the calculated in-between value for a color
     * given integers that represent the start and end values in the four
     * bytes of the 32-bit int. Each channel is separately linearly interpolated
     * and the resulting calculated values are recombined into the return value.
     *
     * @param fraction   The fraction from the starting to the ending values
     * @param startValue A 32-bit int value representing colors in the
     *                   separate bytes of the parameter
     * @param endValue   A 32-bit int value representing colors in the
     *                   separate bytes of the parameter
     * @return A value that is calculated to be the linearly interpolated
     * result, derived by separating the start and end values into separate
     * color channels and interpolating each one separately, recombining the
     * resulting values in the same way.
     */
    public Object evaluate(float fraction, Object startValue, Object endValue) {
        int startInt = (Integer) startValue;
        int startA = (startInt >> 24) & 0xff;
        int startR = (startInt >> 16) & 0xff;
        int startG = (startInt >> 8) & 0xff;
        int startB = startInt & 0xff;
        int endInt = (Integer) endValue;
        int endA = (endInt >> 24) & 0xff;
        int endR = (endInt >> 16) & 0xff;
        int endG = (endInt >> 8) & 0xff;
        int endB = endInt & 0xff;
        return (startA + (int) (fraction * (endA - startA))) << 24 |
                (startR + (int) (fraction * (endR - startR))) << 16 |
                (startG + (int) (fraction * (endG - startG))) << 8 |
                (startB + (int) (fraction * (endB - startB)));
    }
}

================================================
FILE: sample/src/main/java/com/github/ybq/android/loading/Colors.java
================================================
package com.github.ybq.android.loading;

/**
 * Created by ybq.
 */
public interface Colors {
    int[] colors = new int[]{
            0XFFD55400,
            0XFF2B3E51,
            0XFF00BD9C,
            0XFF227FBB,
            0XFF7F8C8D,
            0XFFFFCC5C,
            0XFFD55400,
            0XFF1AAF5D,
    };
}


================================================
FILE: sample/src/main/java/com/github/ybq/android/loading/DetailActivity.java
================================================
package com.github.ybq.android.loading;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.github.ybq.android.spinkit.SpinKitView;
import com.github.ybq.android.spinkit.SpriteFactory;
import com.github.ybq.android.spinkit.Style;
import com.github.ybq.android.spinkit.sprite.Sprite;

import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

public class DetailActivity extends AppCompatActivity implements Colors {

    public static void start(Context context, int position) {
        Intent intent = new Intent(context, DetailActivity.class);
        intent.putExtra("position", position);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);
        ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
        viewPager.setOffscreenPageLimit(0);
        viewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return Style.values().length;
            }

            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }

            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                @SuppressLint("InflateParams") View view = LayoutInflater.from(container.getContext()).inflate(R.layout.item_pager, null);

                SpinKitView spinKitView = (SpinKitView) view.findViewById(R.id.spin_kit);
                TextView name = (TextView) view.findViewById(R.id.name);
                Style style = Style.values()[position];
                name.setText(style.name().toLowerCase());
                Sprite drawable = SpriteFactory.create(style);
                spinKitView.setIndeterminateDrawable(drawable);
                container.addView(view);

                return view;
            }

            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                container.removeView((View) object);
            }
        });

        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                int color = (int) ArgbEvaluator.getInstance().evaluate(positionOffset,
                        colors[position % colors.length],
                        colors[(position + 1) % colors.length]);
                getWindow().getDecorView().setBackgroundColor(color);
            }

            @Override
            public void onPageSelected(int position) {
                getWindow().getDecorView().setBackgroundColor(colors[position % colors.length]);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        viewPager.setCurrentItem(getIntent().getIntExtra("position", 0));
    }
}


================================================
FILE: sample/src/main/java/com/github/ybq/android/loading/MainActivity.java
================================================
package com.github.ybq.android.loading;

import android.os.Bundle;

import com.google.android.material.tabs.TabLayout;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;

public class MainActivity extends AppCompatActivity {

    TabLayout mTabLayout;
    ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTabLayout = (TabLayout) findViewById(R.id.tabs);
        mViewPager = (ViewPager) findViewById(R.id.viewpager);

        mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {

            String[] titles = new String[]{
                    "Style", "Widget"
            };

            @Override
            public Fragment getItem(int position) {
                if (position == 0) {
                    return StyleFragment.newInstance();
                } else {
                    return WidgetFragment.newInstance();
                }
            }

            @Override
            public int getCount() {
                return 2;
            }

            @Override
            public CharSequence getPageTitle(int position) {
                return titles[position];
            }
        });
        mTabLayout.setupWithViewPager(mViewPager);
    }

}


================================================
FILE: sample/src/main/java/com/github/ybq/android/loading/SquareFrameLayout.java
================================================
package com.github.ybq.android.loading;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.FrameLayout;

/**
 * Created by ybq.
 */
public class SquareFrameLayout extends FrameLayout {
    public SquareFrameLayout(Context context) {
        super(context);
    }

    public SquareFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SquareFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @SuppressWarnings("unused")
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public SquareFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //noinspection SuspiciousNameCombination
        super.onMeasure(widthMeasureSpec, widthMeasureSpec);
    }
}


================================================
FILE: sample/src/main/java/com/github/ybq/android/loading/StyleFragment.java
================================================
package com.github.ybq.android.loading;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.github.ybq.android.spinkit.SpinKitView;
import com.github.ybq.android.spinkit.SpriteFactory;
import com.github.ybq.android.spinkit.Style;
import com.github.ybq.android.spinkit.sprite.Sprite;

import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

/**
 * Created by ybq.
 */
public class StyleFragment extends Fragment implements Colors {

    public static StyleFragment newInstance() {
        return new StyleFragment();
    }


    @SuppressLint("InflateParams")
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_style, null);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.list);
        GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 4);
        layoutManager.setOrientation(RecyclerView.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);

        recyclerView.setAdapter(new RecyclerView.Adapter<Holder>() {
            @Override
            public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
                @SuppressLint("InflateParams") View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_style, null);
                return new Holder(view);
            }

            @Override
            public void onBindViewHolder(Holder holder, int position) {
                holder.bind(position);
            }

            @Override
            public int getItemCount() {
                return Style.values().length;
            }
        });
    }

    class Holder extends RecyclerView.ViewHolder {

        SpinKitView spinKitView;

        public Holder(View itemView) {
            super(itemView);
            spinKitView = (SpinKitView) itemView.findViewById(R.id.spin_kit);
        }

        public void bind(int position) {
            itemView.setBackgroundColor(colors[position % colors.length]);
            final int finalPosition = position;
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    DetailActivity.start(v.getContext(), finalPosition);
                }
            });
            position = position % 15;
            Style style = Style.values()[position];
            Sprite drawable = SpriteFactory.create(style);
            spinKitView.setIndeterminateDrawable(drawable);
        }
    }

}


================================================
FILE: sample/src/main/java/com/github/ybq/android/loading/WidgetFragment.java
================================================
package com.github.ybq.android.loading;

import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.github.ybq.android.spinkit.style.ChasingDots;
import com.github.ybq.android.spinkit.style.Circle;
import com.github.ybq.android.spinkit.style.DoubleBounce;
import com.github.ybq.android.spinkit.style.Wave;

import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

/**
 * Created by ybq.
 */
public class WidgetFragment extends Fragment implements Colors {

    private Wave mWaveDrawable;
    private Circle mCircleDrawable;
    private ChasingDots mChasingDotsDrawable;

    public static WidgetFragment newInstance() {
        return new WidgetFragment();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_widget, null);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //ProgressBar
        ProgressBar progressBar = (ProgressBar) view.findViewById(R.id.progress);
        DoubleBounce doubleBounce = new DoubleBounce();
        doubleBounce.setBounds(0, 0, 100, 100);
        doubleBounce.setColor(colors[7]);
        progressBar.setIndeterminateDrawable(doubleBounce);

        //Button
        Button button = (Button) view.findViewById(R.id.button);
        mWaveDrawable = new Wave();
        mWaveDrawable.setBounds(0, 0, 100, 100);
        //noinspection deprecation
        mWaveDrawable.setColor(getResources().getColor(R.color.colorAccent));
        button.setCompoundDrawables(mWaveDrawable, null, null, null);

        //TextView
        TextView textView = (TextView) view.findViewById(R.id.text);
        mCircleDrawable = new Circle();
        mCircleDrawable.setBounds(0, 0, 100, 100);
        mCircleDrawable.setColor(Color.WHITE);
        textView.setCompoundDrawables(null, null, mCircleDrawable, null);
        textView.setBackgroundColor(colors[2]);

        //ImageView
        ImageView imageView = (ImageView) view.findViewById(R.id.image);
        mChasingDotsDrawable = new ChasingDots();
        mChasingDotsDrawable.setColor(Color.WHITE);
        imageView.setImageDrawable(mChasingDotsDrawable);
        imageView.setBackgroundColor(colors[0]);
    }

    @Override
    public void onResume() {
        super.onResume();
        mWaveDrawable.start();
        mCircleDrawable.start();
        mChasingDotsDrawable.start();
    }

    @Override
    public void onStop() {
        super.onStop();
        mWaveDrawable.stop();
        mCircleDrawable.stop();
        mChasingDotsDrawable.stop();
    }
}


================================================
FILE: sample/src/main/res/layout/activity_detail.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:fitsSystemWindows="true">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipChildren="false"
        android:fitsSystemWindows="true" />
</FrameLayout>


================================================
FILE: sample/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>


================================================
FILE: sample/src/main/res/layout/fragment_style.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:fitsSystemWindows="true">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>


================================================
FILE: sample/src/main/res/layout/fragment_widget.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:fitsSystemWindows="true">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="16dp">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="ProgressBar" />

                <ProgressBar
                    android:id="@+id/progress"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="2"
                    android:indeterminate="true" />

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp"
                android:gravity="center_vertical"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="Button" />

                <Button
                    android:id="@+id/button"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="2"
                    android:drawablePadding="10dp"
                    android:text="button" />

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp"
                android:gravity="center_vertical"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="TextView" />

                <TextView
                    android:id="@+id/text"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="2"
                    android:drawablePadding="10dp"
                    android:gravity="center"
                    android:padding="10dp"
                    android:text="TextView" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp"
                android:gravity="center_vertical"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="ImageView" />

                <ImageView
                    android:id="@+id/image"
                    android:layout_width="0dp"
                    android:layout_height="100dp"
                    android:layout_marginTop="10dp"
                    android:layout_weight="2"
                    android:gravity="center"
                    android:padding="10dp" />

            </LinearLayout>

        </LinearLayout>

    </ScrollView>

</FrameLayout>


================================================
FILE: sample/src/main/res/layout/item_pager.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <com.github.ybq.android.spinkit.SpinKitView
        android:id="@+id/spin_kit"
        style="@style/SpinKitView.Large"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:fitsSystemWindows="true"
        android:indeterminate="true" />

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:layout_marginBottom="20dp"
        android:textColor="@android:color/white"
        android:textSize="24sp" />
</FrameLayout>

================================================
FILE: sample/src/main/res/layout/item_style.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<com.github.ybq.android.loading.SquareFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:orientation="vertical">

    <com.github.ybq.android.spinkit.SpinKitView
        android:id="@+id/spin_kit"
        style="@style/SpinKitView"
        android:background="?selectableItemBackgroundBorderless"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:padding="10dp" />

</com.github.ybq.android.loading.SquareFrameLayout>

================================================
FILE: sample/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#00000000</color>
    <color name="colorPrimaryDark">#00000000</color>
    <color name="colorAccent">#FF4081</color>
</resources>


================================================
FILE: sample/src/main/res/values/dimens.xml
================================================
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="fab_margin">16dp</dimen>
</resources>


================================================
FILE: sample/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">SpinKit</string>
</resources>


================================================
FILE: sample/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

</resources>


================================================
FILE: sample/src/main/res/values-v21/styles.xml
================================================
<resources>>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
    </style>
</resources>


================================================
FILE: settings.gradle
================================================
include ':sample', ':library'

Download .txt
gitextract_xp6aiyyo/

├── .gitignore
├── LICENSE
├── README.md
├── README_zh-CN.md
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── library/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── github/
│           │           └── ybq/
│           │               └── android/
│           │                   └── spinkit/
│           │                       ├── SpinKitView.java
│           │                       ├── SpriteFactory.java
│           │                       ├── Style.java
│           │                       ├── animation/
│           │                       │   ├── AnimationUtils.java
│           │                       │   ├── FloatProperty.java
│           │                       │   ├── IntProperty.java
│           │                       │   ├── SpriteAnimatorBuilder.java
│           │                       │   └── interpolator/
│           │                       │       ├── Ease.java
│           │                       │       ├── KeyFrameInterpolator.java
│           │                       │       ├── PathInterpolatorCompat.java
│           │                       │       ├── PathInterpolatorCompatApi21.java
│           │                       │       ├── PathInterpolatorCompatBase.java
│           │                       │       └── PathInterpolatorDonut.java
│           │                       ├── sprite/
│           │                       │   ├── CircleLayoutContainer.java
│           │                       │   ├── CircleSprite.java
│           │                       │   ├── RectSprite.java
│           │                       │   ├── RingSprite.java
│           │                       │   ├── ShapeSprite.java
│           │                       │   ├── Sprite.java
│           │                       │   └── SpriteContainer.java
│           │                       └── style/
│           │                           ├── ChasingDots.java
│           │                           ├── Circle.java
│           │                           ├── CubeGrid.java
│           │                           ├── DoubleBounce.java
│           │                           ├── FadingCircle.java
│           │                           ├── FoldingCube.java
│           │                           ├── MultiplePulse.java
│           │                           ├── MultiplePulseRing.java
│           │                           ├── Pulse.java
│           │                           ├── PulseRing.java
│           │                           ├── RotatingCircle.java
│           │                           ├── RotatingPlane.java
│           │                           ├── ThreeBounce.java
│           │                           ├── WanderingCubes.java
│           │                           └── Wave.java
│           └── res/
│               └── values/
│                   ├── attrs.xml
│                   └── styles.xml
├── sample/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── github/
│           │           └── ybq/
│           │               └── android/
│           │                   └── loading/
│           │                       ├── ArgbEvaluator.java
│           │                       ├── Colors.java
│           │                       ├── DetailActivity.java
│           │                       ├── MainActivity.java
│           │                       ├── SquareFrameLayout.java
│           │                       ├── StyleFragment.java
│           │                       └── WidgetFragment.java
│           └── res/
│               ├── layout/
│               │   ├── activity_detail.xml
│               │   ├── activity_main.xml
│               │   ├── fragment_style.xml
│               │   ├── fragment_widget.xml
│               │   ├── item_pager.xml
│               │   └── item_style.xml
│               ├── values/
│               │   ├── colors.xml
│               │   ├── dimens.xml
│               │   ├── strings.xml
│               │   └── styles.xml
│               └── values-v21/
│                   └── styles.xml
└── settings.gradle
Download .txt
SYMBOL INDEX (304 symbols across 42 files)

FILE: library/src/main/java/com/github/ybq/android/spinkit/SpinKitView.java
  class SpinKitView (line 18) | public class SpinKitView extends ProgressBar {
    method SpinKitView (line 24) | public SpinKitView(Context context) {
    method SpinKitView (line 28) | public SpinKitView(Context context, AttributeSet attrs) {
    method SpinKitView (line 32) | public SpinKitView(Context context, AttributeSet attrs, int defStyleAt...
    method SpinKitView (line 36) | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    method init (line 48) | private void init() {
    method setIndeterminateDrawable (line 54) | @Override
    method setIndeterminateDrawable (line 62) | public void setIndeterminateDrawable(Sprite d) {
    method getIndeterminateDrawable (line 76) | @Override
    method setColor (line 81) | public void setColor(int color) {
    method unscheduleDrawable (line 90) | @Override
    method onWindowFocusChanged (line 99) | @Override
    method onScreenStateChanged (line 110) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/SpriteFactory.java
  class SpriteFactory (line 23) | public class SpriteFactory {
    method create (line 25) | public static Sprite create(Style style) {

FILE: library/src/main/java/com/github/ybq/android/spinkit/Style.java
  type Style (line 6) | public enum Style {
    method Style (line 27) | Style(int value) {

FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/AnimationUtils.java
  class AnimationUtils (line 11) | public class AnimationUtils {
    method start (line 13) | public static void start(Animator animator) {
    method stop (line 19) | public static void stop(Animator animator) {
    method start (line 25) | public static void start(Sprite... sprites) {
    method stop (line 31) | public static void stop(Sprite... sprites) {
    method isRunning (line 37) | public static boolean isRunning(Sprite... sprites) {
    method isRunning (line 46) | public static boolean isRunning(ValueAnimator animator) {
    method isStarted (line 50) | public static boolean isStarted(ValueAnimator animator) {

FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/FloatProperty.java
  class FloatProperty (line 29) | public abstract class FloatProperty<T> extends Property<T, Float> {
    method FloatProperty (line 31) | public FloatProperty(String name) {
    method setValue (line 39) | public abstract void setValue(T object, float value);
    method set (line 41) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/IntProperty.java
  class IntProperty (line 29) | public abstract class IntProperty<T> extends Property<T, Integer> {
    method IntProperty (line 31) | public IntProperty(String name) {
    method setValue (line 39) | public abstract void setValue(T object, int value);
    method set (line 41) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/SpriteAnimatorBuilder.java
  class SpriteAnimatorBuilder (line 21) | public class SpriteAnimatorBuilder {
    class FrameData (line 32) | class FrameData<T> {
      method FrameData (line 33) | public FrameData(float[] fractions, Property property, T[] values) {
    class IntFrameData (line 44) | class IntFrameData extends FrameData<Integer> {
      method IntFrameData (line 46) | public IntFrameData(float[] fractions, Property property, Integer[] ...
    class FloatFrameData (line 51) | class FloatFrameData extends FrameData<Float> {
      method FloatFrameData (line 53) | public FloatFrameData(float[] fractions, Property property, Float[] ...
    method SpriteAnimatorBuilder (line 58) | public SpriteAnimatorBuilder(Sprite sprite) {
    method scale (line 62) | public SpriteAnimatorBuilder scale(float fractions[], Float... scale) {
    method alpha (line 67) | public SpriteAnimatorBuilder alpha(float fractions[], Integer... alpha) {
    method scaleX (line 72) | @SuppressWarnings("unused")
    method scaleY (line 78) | public SpriteAnimatorBuilder scaleY(float fractions[], Float... scaleY) {
    method rotateX (line 83) | public SpriteAnimatorBuilder rotateX(float fractions[], Integer... rot...
    method rotateY (line 88) | public SpriteAnimatorBuilder rotateY(float fractions[], Integer... rot...
    method translateX (line 93) | @SuppressWarnings("unused")
    method translateY (line 100) | @SuppressWarnings("unused")
    method rotate (line 107) | public SpriteAnimatorBuilder rotate(float fractions[], Integer... rota...
    method translateXPercentage (line 112) | public SpriteAnimatorBuilder translateXPercentage(float fractions[], F...
    method translateYPercentage (line 117) | public SpriteAnimatorBuilder translateYPercentage(float[] fractions, F...
    method holder (line 122) | private void holder(float[] fractions, Property property, Float[] valu...
    method holder (line 128) | private void holder(float[] fractions, Property property, Integer[] va...
    method ensurePair (line 133) | private void ensurePair(int fractionsLength, int valuesLength) {
    method interpolator (line 145) | public SpriteAnimatorBuilder interpolator(Interpolator interpolator) {
    method easeInOut (line 150) | public SpriteAnimatorBuilder easeInOut(float... fractions) {
    method duration (line 158) | public SpriteAnimatorBuilder duration(long duration) {
    method repeatCount (line 163) | @SuppressWarnings("unused")
    method startFrame (line 169) | public SpriteAnimatorBuilder startFrame(int startFrame) {
    method build (line 178) | public ObjectAnimator build() {

FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/Ease.java
  class Ease (line 8) | public class Ease {
    method inOut (line 9) | public static Interpolator inOut() {

FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/KeyFrameInterpolator.java
  class KeyFrameInterpolator (line 9) | public class KeyFrameInterpolator implements Interpolator {
    method easeInOut (line 15) | public static KeyFrameInterpolator easeInOut(float... fractions) {
    method pathInterpolator (line 21) | public static KeyFrameInterpolator pathInterpolator(float controlX1, f...
    method KeyFrameInterpolator (line 29) | public KeyFrameInterpolator(TimeInterpolator interpolator, float... fr...
    method setFractions (line 34) | public void setFractions(float... fractions) {
    method getInterpolation (line 38) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/PathInterpolatorCompat.java
  class PathInterpolatorCompat (line 28) | public class PathInterpolatorCompat {
    method PathInterpolatorCompat (line 30) | private PathInterpolatorCompat() {
    method create (line 46) | @SuppressWarnings("unused")
    method create (line 62) | @SuppressWarnings("unused")
    method create (line 80) | public static Interpolator create(float controlX1, float controlY1,

FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/PathInterpolatorCompatApi21.java
  class PathInterpolatorCompatApi21 (line 28) | class PathInterpolatorCompatApi21 {
    method PathInterpolatorCompatApi21 (line 30) | private PathInterpolatorCompatApi21() {
    method create (line 34) | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    method create (line 39) | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    method create (line 44) | @TargetApi(Build.VERSION_CODES.LOLLIPOP)

FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/PathInterpolatorCompatBase.java
  class PathInterpolatorCompatBase (line 25) | class PathInterpolatorCompatBase {
    method PathInterpolatorCompatBase (line 27) | private PathInterpolatorCompatBase() {
    method create (line 31) | public static Interpolator create(Path path) {
    method create (line 35) | public static Interpolator create(float controlX, float controlY) {
    method create (line 39) | public static Interpolator create(float controlX1, float controlY1,

FILE: library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/PathInterpolatorDonut.java
  class PathInterpolatorDonut (line 25) | class PathInterpolatorDonut implements Interpolator {
    method PathInterpolatorDonut (line 35) | public PathInterpolatorDonut(Path path) {
    method PathInterpolatorDonut (line 54) | public PathInterpolatorDonut(float controlX, float controlY) {
    method PathInterpolatorDonut (line 58) | public PathInterpolatorDonut(float controlX1, float controlY1,
    method getInterpolation (line 63) | @Override
    method createQuad (line 97) | private static Path createQuad(float controlX, float controlY) {
    method createCubic (line 104) | private static Path createCubic(float controlX1, float controlY1,

FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/CircleLayoutContainer.java
  class CircleLayoutContainer (line 9) | public abstract class CircleLayoutContainer extends SpriteContainer {
    method drawChild (line 11) | @Override
    method onBoundsChange (line 24) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/CircleSprite.java
  class CircleSprite (line 10) | public class CircleSprite extends ShapeSprite {
    method onCreateAnimation (line 12) | @Override
    method drawShape (line 17) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/RectSprite.java
  class RectSprite (line 10) | public class RectSprite extends ShapeSprite {
    method onCreateAnimation (line 11) | @Override
    method drawShape (line 16) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/RingSprite.java
  class RingSprite (line 10) | public class RingSprite extends ShapeSprite {
    method drawShape (line 13) | @Override
    method onCreateAnimation (line 25) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/ShapeSprite.java
  class ShapeSprite (line 11) | public abstract class ShapeSprite extends Sprite {
    method ShapeSprite (line 17) | public ShapeSprite() {
    method setColor (line 24) | @Override
    method getColor (line 30) | @Override
    method getUseColor (line 35) | @SuppressWarnings("unused")
    method setAlpha (line 40) | @Override
    method updateUseColor (line 46) | private void updateUseColor() {
    method setColorFilter (line 54) | @Override
    method drawSelf (line 59) | @Override
    method drawShape (line 65) | public abstract void drawShape(Canvas canvas, Paint paint);

FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/Sprite.java
  class Sprite (line 21) | public abstract class Sprite extends Drawable implements
    method Sprite (line 46) | public Sprite() {
    method getColor (line 51) | public abstract int getColor();
    method setColor (line 53) | public abstract void setColor(int color);
    method setAlpha (line 55) | @Override
    method getAlpha (line 60) | @Override
    method getOpacity (line 65) | @Override
    method getTranslateXPercentage (line 70) | public float getTranslateXPercentage() {
    method setTranslateXPercentage (line 74) | public void setTranslateXPercentage(float translateXPercentage) {
    method getTranslateYPercentage (line 78) | public float getTranslateYPercentage() {
    method setTranslateYPercentage (line 82) | public void setTranslateYPercentage(float translateYPercentage) {
    method getTranslateX (line 86) | public int getTranslateX() {
    method setTranslateX (line 90) | public void setTranslateX(int translateX) {
    method getTranslateY (line 94) | public int getTranslateY() {
    method setTranslateY (line 98) | public void setTranslateY(int translateY) {
    method getRotate (line 102) | public int getRotate() {
    method setRotate (line 106) | public void setRotate(int rotate) {
    method getScale (line 110) | public float getScale() {
    method setScale (line 114) | public void setScale(float scale) {
    method getScaleX (line 120) | public float getScaleX() {
    method setScaleX (line 124) | public void setScaleX(float scaleX) {
    method getScaleY (line 128) | public float getScaleY() {
    method setScaleY (line 132) | public void setScaleY(float scaleY) {
    method getRotateX (line 136) | public int getRotateX() {
    method setRotateX (line 140) | public void setRotateX(int rotateX) {
    method getRotateY (line 144) | public int getRotateY() {
    method setRotateY (line 148) | public void setRotateY(int rotateY) {
    method getPivotX (line 152) | public float getPivotX() {
    method setPivotX (line 156) | public void setPivotX(float pivotX) {
    method getPivotY (line 160) | public float getPivotY() {
    method setPivotY (line 164) | public void setPivotY(float pivotY) {
    method getAnimationDelay (line 168) | @SuppressWarnings("unused")
    method setAnimationDelay (line 173) | public Sprite setAnimationDelay(int animationDelay) {
    method setColorFilter (line 178) | @Override
    method onCreateAnimation (line 183) | public abstract ValueAnimator onCreateAnimation();
    method start (line 185) | @Override
    method obtainAnimation (line 200) | public ValueAnimator obtainAnimation() {
    method stop (line 211) | @Override
    method drawSelf (line 220) | protected abstract void drawSelf(Canvas canvas);
    method reset (line 222) | public void reset() {
    method isRunning (line 233) | @Override
    method onBoundsChange (line 238) | @Override
    method setDrawBounds (line 244) | public void setDrawBounds(Rect drawBounds) {
    method setDrawBounds (line 248) | public void setDrawBounds(int left, int top, int right, int bottom) {
    method invalidateDrawable (line 254) | @Override
    method scheduleDrawable (line 259) | @Override
    method unscheduleDrawable (line 264) | @Override
    method onAnimationUpdate (line 269) | @Override
    method getDrawBounds (line 277) | public Rect getDrawBounds() {
    method draw (line 281) | @Override
    method clipSquare (line 304) | public Rect clipSquare(Rect rect) {
    method setValue (line 320) | @Override
    method get (line 325) | @Override
    method setValue (line 332) | @Override
    method get (line 337) | @Override
    method setValue (line 344) | @Override
    method get (line 349) | @Override
    method setValue (line 357) | @Override
    method get (line 362) | @Override
    method setValue (line 370) | @Override
    method get (line 375) | @Override
    method setValue (line 382) | @Override
    method get (line 387) | @Override
    method setValue (line 394) | @Override
    method get (line 399) | @Override
    method setValue (line 407) | @Override
    method get (line 412) | @Override
    method setValue (line 419) | @Override
    method get (line 424) | @Override
    method setValue (line 431) | @Override
    method get (line 436) | @Override
    method setValue (line 443) | @Override
    method get (line 448) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/sprite/SpriteContainer.java
  class SpriteContainer (line 12) | public abstract class SpriteContainer extends Sprite {
    method SpriteContainer (line 18) | public SpriteContainer() {
    method initCallBack (line 24) | private void initCallBack() {
    method onChildCreated (line 32) | public void onChildCreated(Sprite... sprites) {
    method getChildCount (line 36) | public int getChildCount() {
    method getChildAt (line 40) | public Sprite getChildAt(int index) {
    method setColor (line 44) | @Override
    method getColor (line 52) | @Override
    method draw (line 57) | @Override
    method drawChild (line 63) | public void drawChild(Canvas canvas) {
    method drawSelf (line 73) | @Override
    method onBoundsChange (line 77) | @Override
    method start (line 85) | @Override
    method stop (line 91) | @Override
    method isRunning (line 97) | @Override
    method onCreateChild (line 102) | public abstract Sprite[] onCreateChild();
    method onCreateAnimation (line 104) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/ChasingDots.java
  class ChasingDots (line 16) | public class ChasingDots extends SpriteContainer {
    method onCreateChild (line 18) | @Override
    method onChildCreated (line 26) | @Override
    method onCreateAnimation (line 36) | @Override
    method onBoundsChange (line 46) | @Override
    class Dot (line 65) | private class Dot extends CircleSprite {
      method Dot (line 67) | Dot() {
      method onCreateAnimation (line 71) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/Circle.java
  class Circle (line 14) | public class Circle extends CircleLayoutContainer {
    method onCreateChild (line 16) | @Override
    class Dot (line 30) | private class Dot extends CircleSprite {
      method Dot (line 32) | Dot() {
      method onCreateAnimation (line 36) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/CubeGrid.java
  class CubeGrid (line 14) | public class CubeGrid extends SpriteContainer {
    method onCreateChild (line 16) | @Override
    method onBoundsChange (line 31) | @Override
    class GridItem (line 47) | private class GridItem extends RectSprite {
      method onCreateAnimation (line 48) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/DoubleBounce.java
  class DoubleBounce (line 14) | public class DoubleBounce extends SpriteContainer {
    method onCreateChild (line 16) | @Override
    method onChildCreated (line 23) | @Override
    class Bounce (line 33) | private class Bounce extends CircleSprite {
      method Bounce (line 35) | Bounce() {
      method onCreateAnimation (line 40) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/FadingCircle.java
  class FadingCircle (line 14) | public class FadingCircle extends CircleLayoutContainer {
    method onCreateChild (line 16) | @Override
    class Dot (line 30) | private class Dot extends CircleSprite {
      method Dot (line 32) | Dot() {
      method onCreateAnimation (line 36) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/FoldingCube.java
  class FoldingCube (line 17) | public class FoldingCube extends SpriteContainer {
    method onCreateChild (line 22) | @Override
    method onBoundsChange (line 38) | @Override
    method drawChild (line 72) | @Override
    class Cube (line 85) | private class Cube extends RectSprite {
      method Cube (line 87) | Cube() {
      method onCreateAnimation (line 92) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/MultiplePulse.java
  class MultiplePulse (line 9) | public class MultiplePulse extends SpriteContainer {
    method onCreateChild (line 10) | @Override
    method onChildCreated (line 19) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/MultiplePulseRing.java
  class MultiplePulseRing (line 9) | public class MultiplePulseRing extends SpriteContainer {
    method onCreateChild (line 11) | @Override
    method onChildCreated (line 20) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/Pulse.java
  class Pulse (line 11) | public class Pulse extends CircleSprite {
    method Pulse (line 13) | public Pulse() {
    method onCreateAnimation (line 17) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/PulseRing.java
  class PulseRing (line 12) | public class PulseRing extends RingSprite {
    method PulseRing (line 14) | public PulseRing() {
    method onCreateAnimation (line 18) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/RotatingCircle.java
  class RotatingCircle (line 8) | public class RotatingCircle extends CircleSprite {
    method onCreateAnimation (line 10) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/RotatingPlane.java
  class RotatingPlane (line 12) | public class RotatingPlane extends RectSprite {
    method onBoundsChange (line 13) | @Override
    method onCreateAnimation (line 18) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/ThreeBounce.java
  class ThreeBounce (line 14) | public class ThreeBounce extends SpriteContainer {
    method onCreateChild (line 16) | @Override
    method onChildCreated (line 25) | @Override
    method onBoundsChange (line 32) | @Override
    class Bounce (line 49) | private class Bounce extends CircleSprite {
      method Bounce (line 51) | Bounce() {
      method onCreateAnimation (line 55) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/WanderingCubes.java
  class WanderingCubes (line 15) | public class WanderingCubes extends SpriteContainer {
    method onCreateChild (line 17) | @Override
    method onChildCreated (line 25) | @Override
    method onBoundsChange (line 33) | @Override
    class Cube (line 48) | private class Cube extends RectSprite {
      method Cube (line 51) | public Cube(int startFrame) {
      method onCreateAnimation (line 55) | @Override

FILE: library/src/main/java/com/github/ybq/android/spinkit/style/Wave.java
  class Wave (line 15) | public class Wave extends SpriteContainer {
    method onCreateChild (line 17) | @Override
    method onBoundsChange (line 32) | @Override
    class WaveItem (line 46) | private class WaveItem extends RectSprite {
      method WaveItem (line 48) | WaveItem() {
      method onCreateAnimation (line 52) | @Override

FILE: sample/src/main/java/com/github/ybq/android/loading/ArgbEvaluator.java
  class ArgbEvaluator (line 26) | public class ArgbEvaluator implements TypeEvaluator {
    method getInstance (line 36) | public static ArgbEvaluator getInstance() {
    method evaluate (line 56) | public Object evaluate(float fraction, Object startValue, Object endVa...

FILE: sample/src/main/java/com/github/ybq/android/loading/Colors.java
  type Colors (line 6) | public interface Colors {

FILE: sample/src/main/java/com/github/ybq/android/loading/DetailActivity.java
  class DetailActivity (line 21) | public class DetailActivity extends AppCompatActivity implements Colors {
    method start (line 23) | public static void start(Context context, int position) {
    method onCreate (line 29) | @Override

FILE: sample/src/main/java/com/github/ybq/android/loading/MainActivity.java
  class MainActivity (line 12) | public class MainActivity extends AppCompatActivity {
    method onCreate (line 17) | @Override

FILE: sample/src/main/java/com/github/ybq/android/loading/SquareFrameLayout.java
  class SquareFrameLayout (line 12) | public class SquareFrameLayout extends FrameLayout {
    method SquareFrameLayout (line 13) | public SquareFrameLayout(Context context) {
    method SquareFrameLayout (line 17) | public SquareFrameLayout(Context context, AttributeSet attrs) {
    method SquareFrameLayout (line 21) | public SquareFrameLayout(Context context, AttributeSet attrs, int defS...
    method SquareFrameLayout (line 25) | @SuppressWarnings("unused")
    method onMeasure (line 31) | @Override

FILE: sample/src/main/java/com/github/ybq/android/loading/StyleFragment.java
  class StyleFragment (line 22) | public class StyleFragment extends Fragment implements Colors {
    method newInstance (line 24) | public static StyleFragment newInstance() {
    method onCreateView (line 29) | @SuppressLint("InflateParams")
    method onViewCreated (line 36) | @Override
    class Holder (line 63) | class Holder extends RecyclerView.ViewHolder {
      method Holder (line 67) | public Holder(View itemView) {
      method bind (line 72) | public void bind(int position) {

FILE: sample/src/main/java/com/github/ybq/android/loading/WidgetFragment.java
  class WidgetFragment (line 24) | public class WidgetFragment extends Fragment implements Colors {
    method newInstance (line 30) | public static WidgetFragment newInstance() {
    method onCreateView (line 34) | @Nullable
    method onViewCreated (line 40) | @Override
    method onResume (line 75) | @Override
    method onStop (line 83) | @Override
Condensed preview — 75 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (135K chars).
[
  {
    "path": ".gitignore",
    "chars": 445,
    "preview": "# Built application files\n*.apk\n*.ap_\n\n# Files for the Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbi"
  },
  {
    "path": "LICENSE",
    "chars": 1527,
    "preview": "The MIT License (MIT)\n\nCopyright © 2016 ybq\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
  },
  {
    "path": "README.md",
    "chars": 3315,
    "preview": "# Android-SpinKit\n>Android loading animations(I wrote a android edition according [SpinKit](https://tobiasahlin.com/spin"
  },
  {
    "path": "README_zh-CN.md",
    "chars": 3100,
    "preview": "\n# Android-SpinKit\n \n> Android 加载动画([SpinKit](https://tobiasahlin.com/spinkit)的Android版本实现)\n\n[Demo Apk](https://raw.gith"
  },
  {
    "path": "build.gradle",
    "chars": 350,
    "preview": "buildscript {\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.andr"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 230,
    "preview": "#Tue Nov 14 15:17:22 WET 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradle.properties",
    "chars": 908,
    "preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
  },
  {
    "path": "gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2314,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
  },
  {
    "path": "library/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "library/build.gradle",
    "chars": 527,
    "preview": "apply plugin: 'com.android.library'\napply plugin: 'com.novoda.bintray-release'\n\nandroid {\n\n    compileSdkVersion 28\n    "
  },
  {
    "path": "library/gradle.properties",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "library/proguard-rules.pro",
    "chars": 661,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "library/src/main/AndroidManifest.xml",
    "chars": 54,
    "preview": "<manifest package=\"com.github.ybq.android.spinkit\" />\n"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/SpinKitView.java",
    "chars": 3283,
    "preview": "package com.github.ybq.android.spinkit;\n\nimport android.annotation.TargetApi;\nimport android.content.Context;\nimport and"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/SpriteFactory.java",
    "chars": 2647,
    "preview": "package com.github.ybq.android.spinkit;\n\nimport com.github.ybq.android.spinkit.sprite.Sprite;\nimport com.github.ybq.andr"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/Style.java",
    "chars": 539,
    "preview": "package com.github.ybq.android.spinkit;\n\n/**\n * Created by ybq.\n */\npublic enum Style {\n\n    ROTATING_PLANE(0),\n    DOUB"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/animation/AnimationUtils.java",
    "chars": 1282,
    "preview": "package com.github.ybq.android.spinkit.animation;\n\nimport android.animation.Animator;\nimport android.animation.ValueAnim"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/animation/FloatProperty.java",
    "chars": 1633,
    "preview": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/animation/IntProperty.java",
    "chars": 1633,
    "preview": "/*\n * Copyright (C) 2011 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/animation/SpriteAnimatorBuilder.java",
    "chars": 7049,
    "preview": "package com.github.ybq.android.spinkit.animation;\n\nimport android.animation.Keyframe;\nimport android.animation.ObjectAni"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/Ease.java",
    "chars": 273,
    "preview": "package com.github.ybq.android.spinkit.animation.interpolator;\n\nimport android.view.animation.Interpolator;\n\n/**\n * Crea"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/KeyFrameInterpolator.java",
    "chars": 1924,
    "preview": "package com.github.ybq.android.spinkit.animation.interpolator;\n\nimport android.animation.TimeInterpolator;\nimport androi"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/PathInterpolatorCompat.java",
    "chars": 3793,
    "preview": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/PathInterpolatorCompatApi21.java",
    "chars": 1666,
    "preview": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/PathInterpolatorCompatBase.java",
    "chars": 1431,
    "preview": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/animation/interpolator/PathInterpolatorDonut.java",
    "chars": 3602,
    "preview": "/*\n * Copyright (C) 2015 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/sprite/CircleLayoutContainer.java",
    "chars": 1140,
    "preview": "package com.github.ybq.android.spinkit.sprite;\n\nimport android.graphics.Canvas;\nimport android.graphics.Rect;\n\n/**\n * Cr"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/sprite/CircleSprite.java",
    "chars": 674,
    "preview": "package com.github.ybq.android.spinkit.sprite;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Canvas;\n"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/sprite/RectSprite.java",
    "chars": 494,
    "preview": "package com.github.ybq.android.spinkit.sprite;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Canvas;\n"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/sprite/RingSprite.java",
    "chars": 768,
    "preview": "package com.github.ybq.android.spinkit.sprite;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Canvas;\n"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/sprite/ShapeSprite.java",
    "chars": 1510,
    "preview": "package com.github.ybq.android.spinkit.sprite;\n\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport an"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/sprite/Sprite.java",
    "chars": 11641,
    "preview": "package com.github.ybq.android.spinkit.sprite;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Camera;\n"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/sprite/SpriteContainer.java",
    "chars": 2315,
    "preview": "package com.github.ybq.android.spinkit.sprite;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Canvas;\n"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/ChasingDots.java",
    "chars": 2305,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Rect;\nimp"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/Circle.java",
    "chars": 1329,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\nimport android.os.Build;\n\nimport "
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/CubeGrid.java",
    "chars": 1846,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Rect;\n\nim"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/DoubleBounce.java",
    "chars": 1345,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\nimport android.os.Build;\n\nimport "
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/FadingCircle.java",
    "chars": 1322,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\nimport android.os.Build;\n\nimport "
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/FoldingCube.java",
    "chars": 3262,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Canvas;\ni"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/MultiplePulse.java",
    "chars": 621,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport com.github.ybq.android.spinkit.sprite.Sprite;\nimport com.github.yb"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/MultiplePulseRing.java",
    "chars": 638,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport com.github.ybq.android.spinkit.sprite.Sprite;\nimport com.github.yb"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/Pulse.java",
    "chars": 684,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\n\nimport com.github.ybq.android.sp"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/PulseRing.java",
    "chars": 869,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\n\nimport com.github.ybq.android.sp"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/RotatingCircle.java",
    "chars": 637,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\n\nimport com.github.ybq.android.sp"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/RotatingPlane.java",
    "chars": 801,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Rect;\n\nim"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/ThreeBounce.java",
    "chars": 1814,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Rect;\n\nim"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/WanderingCubes.java",
    "chars": 2307,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Rect;\nimp"
  },
  {
    "path": "library/src/main/java/com/github/ybq/android/spinkit/style/Wave.java",
    "chars": 1887,
    "preview": "package com.github.ybq.android.spinkit.style;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Rect;\nimp"
  },
  {
    "path": "library/src/main/res/values/attrs.xml",
    "chars": 1044,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <attr name=\"SpinKitViewStyle\" format=\"reference\" />\n\n    <declare"
  },
  {
    "path": "library/src/main/res/values/styles.xml",
    "chars": 6032,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <style name=\"SpinKitView\">\n        <item name=\"android:indetermi"
  },
  {
    "path": "sample/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "sample/build.gradle",
    "chars": 710,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n\n    compileSdkVersion 28\n    buildToolsVersion '28.0.3'\n\n    default"
  },
  {
    "path": "sample/proguard-rules.pro",
    "chars": 661,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "sample/src/main/AndroidManifest.xml",
    "chars": 1042,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "sample/src/main/java/com/github/ybq/android/loading/ArgbEvaluator.java",
    "chars": 3078,
    "preview": "\n/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lic"
  },
  {
    "path": "sample/src/main/java/com/github/ybq/android/loading/Colors.java",
    "chars": 325,
    "preview": "package com.github.ybq.android.loading;\n\n/**\n * Created by ybq.\n */\npublic interface Colors {\n    int[] colors = new int"
  },
  {
    "path": "sample/src/main/java/com/github/ybq/android/loading/DetailActivity.java",
    "chars": 3341,
    "preview": "package com.github.ybq.android.loading;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\nimport "
  },
  {
    "path": "sample/src/main/java/com/github/ybq/android/loading/MainActivity.java",
    "chars": 1473,
    "preview": "package com.github.ybq.android.loading;\n\nimport android.os.Bundle;\n\nimport com.google.android.material.tabs.TabLayout;\n\n"
  },
  {
    "path": "sample/src/main/java/com/github/ybq/android/loading/SquareFrameLayout.java",
    "chars": 1061,
    "preview": "package com.github.ybq.android.loading;\n\nimport android.annotation.TargetApi;\nimport android.content.Context;\nimport and"
  },
  {
    "path": "sample/src/main/java/com/github/ybq/android/loading/StyleFragment.java",
    "chars": 2970,
    "preview": "package com.github.ybq.android.loading;\n\nimport android.annotation.SuppressLint;\nimport android.os.Bundle;\nimport androi"
  },
  {
    "path": "sample/src/main/java/com/github/ybq/android/loading/WidgetFragment.java",
    "chars": 2932,
    "preview": "package com.github.ybq.android.loading;\n\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport android.view.La"
  },
  {
    "path": "sample/src/main/res/layout/activity_detail.xml",
    "chars": 527,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andro"
  },
  {
    "path": "sample/src/main/res/layout/activity_main.xml",
    "chars": 657,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "sample/src/main/res/layout/fragment_style.xml",
    "chars": 449,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andro"
  },
  {
    "path": "sample/src/main/res/layout/fragment_widget.xml",
    "chars": 4082,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andro"
  },
  {
    "path": "sample/src/main/res/layout/item_pager.xml",
    "chars": 967,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andro"
  },
  {
    "path": "sample/src/main/res/layout/item_style.xml",
    "chars": 697,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.github.ybq.android.loading.SquareFrameLayout xmlns:android=\"http://schemas.a"
  },
  {
    "path": "sample/src/main/res/values/colors.xml",
    "chars": 212,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#00000000</color>\n    <color name=\"col"
  },
  {
    "path": "sample/src/main/res/values/dimens.xml",
    "chars": 253,
    "preview": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal"
  },
  {
    "path": "sample/src/main/res/values/strings.xml",
    "chars": 70,
    "preview": "<resources>\n    <string name=\"app_name\">SpinKit</string>\n</resources>\n"
  },
  {
    "path": "sample/src/main/res/values/styles.xml",
    "chars": 708,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
  },
  {
    "path": "sample/src/main/res/values-v21/styles.xml",
    "chars": 311,
    "preview": "<resources>>\n\n    <style name=\"AppTheme.NoActionBar\">\n        <item name=\"windowActionBar\">false</item>\n        <item na"
  },
  {
    "path": "settings.gradle",
    "chars": 31,
    "preview": "include ':sample', ':library'\n\n"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the ybq/Android-SpinKit GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 75 files (120.1 KB), approximately 31.2k tokens, and a symbol index with 304 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!