diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c0d3b63
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,37 @@
+# built application files
+*.apk
+*.ap_
+
+# files for the dex VM
+*.dex
+
+# Java class files
+*.class
+.DS_Store
+
+# generated files
+bin/
+gen/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Eclipse project files
+.classpath
+.project
+.settings/
+
+# Proguard folder generated by Eclipse
+proguard/
+
+#Android Studio
+build/
+
+# Intellij project files
+*.iml
+*.ipr
+*.iws
+.idea/
+
+#gradle
+.gradle/
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..80eec1a
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,16 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.9.+'
+ }
+}
+
+allprojects {
+ repositories {
+ mavenCentral()
+ }
+}
diff --git a/demo/.gitignore b/demo/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/demo/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/demo/build.gradle b/demo/build.gradle
new file mode 100644
index 0000000..34ee5a2
--- /dev/null
+++ b/demo/build.gradle
@@ -0,0 +1,26 @@
+apply plugin: 'android'
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.1.0"
+
+ defaultConfig {
+ minSdkVersion 8
+ targetSdkVersion 19
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ runProguard false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile project(':library')
+ compile 'com.android.support:gridlayout-v7:18.0.+'
+ compile 'com.android.support:appcompat-v7:19.+'
+}
diff --git a/demo/proguard-rules.txt b/demo/proguard-rules.txt
new file mode 100644
index 0000000..cb8998d
--- /dev/null
+++ b/demo/proguard-rules.txt
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# 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 *;
+#}
\ No newline at end of file
diff --git a/demo/src/main/AndroidManifest.xml b/demo/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..1144807
--- /dev/null
+++ b/demo/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/src/main/assets/nemo.jpg b/demo/src/main/assets/nemo.jpg
new file mode 100644
index 0000000..3d896be
Binary files /dev/null and b/demo/src/main/assets/nemo.jpg differ
diff --git a/demo/src/main/assets/toystory.jpg b/demo/src/main/assets/toystory.jpg
new file mode 100644
index 0000000..00bb01f
Binary files /dev/null and b/demo/src/main/assets/toystory.jpg differ
diff --git a/demo/src/main/assets/up.jpg b/demo/src/main/assets/up.jpg
new file mode 100644
index 0000000..3f332a9
Binary files /dev/null and b/demo/src/main/assets/up.jpg differ
diff --git a/demo/src/main/assets/wall.jpg b/demo/src/main/assets/wall.jpg
new file mode 100644
index 0000000..f03ddcf
Binary files /dev/null and b/demo/src/main/assets/wall.jpg differ
diff --git a/demo/src/main/java/com/daimajia/slider/demo/MainActivity.java b/demo/src/main/java/com/daimajia/slider/demo/MainActivity.java
new file mode 100644
index 0000000..0d25aeb
--- /dev/null
+++ b/demo/src/main/java/com/daimajia/slider/demo/MainActivity.java
@@ -0,0 +1,92 @@
+package com.daimajia.slider.demo;
+
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.daimajia.slider.library.RenderTypes.BaseSliderView;
+import com.daimajia.slider.library.RenderTypes.TextSliderView;
+import com.daimajia.slider.library.SliderLayout;
+
+import java.util.HashMap;
+
+
+public class MainActivity extends ActionBarActivity implements BaseSliderView.OnSliderClickListener{
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ final SliderLayout slider = (SliderLayout)findViewById(R.id.slider);
+
+ HashMap url_maps = new HashMap();
+ url_maps.put("Hannibal", "http://static2.hypable.com/wp-content/uploads/2013/12/hannibal-season-2-release-date.jpg");
+ url_maps.put("Big Bang Theory", "http://tvfiles.alphacoders.com/100/hdclearart-10.png");
+ url_maps.put("House of Cards", "http://cdn3.nflximg.net/images/3093/2043093.jpg");
+ url_maps.put("Game of Thrones", "http://images.boomsbeat.com/data/images/full/19640/game-of-thrones-season-4-jpg.jpg");
+
+ HashMap file_maps = new HashMap();
+ file_maps.put("Hannibal",R.drawable.hannibal);
+ file_maps.put("Big Bang Theory",R.drawable.bigbang);
+ file_maps.put("House of Cards",R.drawable.house);
+ file_maps.put("Game of Thrones",R.drawable.game_of_thrones);
+
+ for(String name : url_maps.keySet()){
+ TextSliderView textSliderView = new TextSliderView(this);
+ // initialize a sliderview
+ textSliderView
+ .description(name)
+ .image(file_maps.get(name))
+ .errorDisappear(true)
+ .setOnSliderClickListener(this);
+
+ //add your extra information
+ textSliderView.getBundle()
+ .putString("extra",name);
+
+ slider.addSlider(textSliderView);
+ }
+ slider.startCycle();
+ slider.setPresetTransformer(SliderLayout.Transformer.Stack);
+
+ ListView l = (ListView)findViewById(R.id.transformers);
+ l.setAdapter(new TransformerAdapter(this));
+
+ l.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ slider.setPresetTransformer(((TextView)view).getText().toString());
+ Toast.makeText(MainActivity.this,((TextView)view).getText().toString(),Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int id = item.getItemId();
+ if (id == R.id.action_settings) {
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public void onSliderClick(BaseSliderView slider) {
+ Toast.makeText(this,slider.getBundle().get("extra") + "",Toast.LENGTH_SHORT).show();
+ }
+
+}
diff --git a/demo/src/main/java/com/daimajia/slider/demo/TransformerAdapter.java b/demo/src/main/java/com/daimajia/slider/demo/TransformerAdapter.java
new file mode 100644
index 0000000..094d300
--- /dev/null
+++ b/demo/src/main/java/com/daimajia/slider/demo/TransformerAdapter.java
@@ -0,0 +1,42 @@
+package com.daimajia.slider.demo;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import com.daimajia.slider.library.SliderLayout;
+
+/**
+ * Created by daimajia on 14-5-29.
+ */
+public class TransformerAdapter extends BaseAdapter{
+ private Context mContext;
+ public TransformerAdapter(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public int getCount() {
+ return SliderLayout.Transformer.values().length;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return SliderLayout.Transformer.values()[position].toString();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView t = (TextView)LayoutInflater.from(mContext).inflate(R.layout.item,null);
+ t.setText(getItem(position).toString());
+ return t;
+ }
+}
diff --git a/demo/src/main/res/drawable-hdpi/bigbang.jpg b/demo/src/main/res/drawable-hdpi/bigbang.jpg
new file mode 100644
index 0000000..611d0e0
Binary files /dev/null and b/demo/src/main/res/drawable-hdpi/bigbang.jpg differ
diff --git a/demo/src/main/res/drawable-hdpi/game_of_thrones.jpg b/demo/src/main/res/drawable-hdpi/game_of_thrones.jpg
new file mode 100644
index 0000000..42eb59d
Binary files /dev/null and b/demo/src/main/res/drawable-hdpi/game_of_thrones.jpg differ
diff --git a/demo/src/main/res/drawable-hdpi/hannibal.jpg b/demo/src/main/res/drawable-hdpi/hannibal.jpg
new file mode 100644
index 0000000..17d33d2
Binary files /dev/null and b/demo/src/main/res/drawable-hdpi/hannibal.jpg differ
diff --git a/demo/src/main/res/drawable-hdpi/house.jpg b/demo/src/main/res/drawable-hdpi/house.jpg
new file mode 100644
index 0000000..75a82be
Binary files /dev/null and b/demo/src/main/res/drawable-hdpi/house.jpg differ
diff --git a/demo/src/main/res/drawable-hdpi/ic_launcher.png b/demo/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/demo/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/demo/src/main/res/drawable-mdpi/ic_launcher.png b/demo/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/demo/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/demo/src/main/res/drawable-xhdpi/ic_launcher.png b/demo/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/demo/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/demo/src/main/res/drawable-xxhdpi/ic_launcher.png b/demo/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/demo/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/demo/src/main/res/layout/activity_main.xml b/demo/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..1d49efe
--- /dev/null
+++ b/demo/src/main/res/layout/activity_main.xml
@@ -0,0 +1,18 @@
+
+
+
+
diff --git a/demo/src/main/res/layout/item.xml b/demo/src/main/res/layout/item.xml
new file mode 100644
index 0000000..2b0c390
--- /dev/null
+++ b/demo/src/main/res/layout/item.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/demo/src/main/res/menu/main.xml b/demo/src/main/res/menu/main.xml
new file mode 100644
index 0000000..957ac76
--- /dev/null
+++ b/demo/src/main/res/menu/main.xml
@@ -0,0 +1,9 @@
+
diff --git a/demo/src/main/res/values-w820dp/dimens.xml b/demo/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/demo/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/demo/src/main/res/values/dimens.xml b/demo/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..47c8224
--- /dev/null
+++ b/demo/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+
+
+ 16dp
+ 16dp
+
diff --git a/demo/src/main/res/values/strings.xml b/demo/src/main/res/values/strings.xml
new file mode 100644
index 0000000..cfc48a1
--- /dev/null
+++ b/demo/src/main/res/values/strings.xml
@@ -0,0 +1,8 @@
+
+
+
+ AndroidImageSlider
+ Hello world!
+ Settings
+
+
diff --git a/demo/src/main/res/values/styles.xml b/demo/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/demo/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..5d08ba7
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Settings specified in this file will override any Gradle settings
+# configured through the IDE.
+
+# 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
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..5de946b
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..91a7e26
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,164 @@
+#!/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
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# 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\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+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"`
+
+ # 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 "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,90 @@
+@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
diff --git a/library/.gitignore b/library/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/library/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/library/build.gradle b/library/build.gradle
new file mode 100644
index 0000000..b1739c2
--- /dev/null
+++ b/library/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: 'android-library'
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.1.0"
+
+ defaultConfig {
+ minSdkVersion 8
+ targetSdkVersion 19
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ runProguard false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:19.+'
+ compile 'pl.droidsonroids.gif:android-gif-drawable:1.0.+'
+}
diff --git a/library/libs/nineoldandroids-2.4.0.jar b/library/libs/nineoldandroids-2.4.0.jar
new file mode 100644
index 0000000..43ee45f
Binary files /dev/null and b/library/libs/nineoldandroids-2.4.0.jar differ
diff --git a/library/libs/picasso-2.2.0.jar b/library/libs/picasso-2.2.0.jar
new file mode 100644
index 0000000..4acc056
Binary files /dev/null and b/library/libs/picasso-2.2.0.jar differ
diff --git a/library/proguard-rules.txt b/library/proguard-rules.txt
new file mode 100644
index 0000000..cb8998d
--- /dev/null
+++ b/library/proguard-rules.txt
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# 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 *;
+#}
\ No newline at end of file
diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..687af51
--- /dev/null
+++ b/library/src/main/AndroidManifest.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/java/com/daimajia/slider/library/Indicators/PagerIndicator.java b/library/src/main/java/com/daimajia/slider/library/Indicators/PagerIndicator.java
new file mode 100644
index 0000000..b98f202
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Indicators/PagerIndicator.java
@@ -0,0 +1,147 @@
+package com.daimajia.slider.library.Indicators;
+
+import android.content.Context;
+import android.database.DataSetObserver;
+import android.graphics.drawable.Drawable;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import com.daimajia.slider.library.Infinity.InfinitePagerAdapter;
+import com.daimajia.slider.library.R;
+
+import java.util.ArrayList;
+
+/**
+ * Created by daimajia on 14-5-27.
+ */
+public class PagerIndicator extends LinearLayout implements ViewPager.OnPageChangeListener{
+
+ private Context mContext;
+ private ViewPager mPager;
+ private ImageView mPreviousSelectedIndicator;
+ private int mPreviousSelectedPosition;
+
+ private int mUserSetUnSelectedIndicatorResId;
+ private int mUserSetSelectedIndicatorResId;
+
+ private Drawable mSelectedDrawable;
+ private Drawable mUnselectedDrawable;
+
+ private int mItemCount = 0;
+ private int mRealItemCount = 0;
+
+ private ArrayList mIndicators = new ArrayList();
+
+ public PagerIndicator(Context context) {
+ this(context,null);
+ }
+
+ public PagerIndicator(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mContext = context;
+ LayoutInflater.from(context).inflate(R.layout.indicator_layout,this,true);
+
+ mSelectedDrawable = getResources().getDrawable(R.drawable.circle_selected_layer);
+ mUnselectedDrawable = getResources().getDrawable(R.drawable.circle_common_layer);
+ }
+
+ public void setViewPager(ViewPager pager){
+ if(pager.getAdapter() == null){
+ throw new IllegalStateException("Viewpager does not have adapter instance");
+ }
+ mPager = pager;
+ mPager.setOnPageChangeListener(this);
+ ((InfinitePagerAdapter)mPager.getAdapter()).getRealAdapter().registerDataSetObserver(dataChangeObserver);
+ }
+
+ public void setIndicator(int selected,int unselected){
+ mUserSetSelectedIndicatorResId = selected;
+ mUserSetUnSelectedIndicatorResId = unselected;
+
+ mSelectedDrawable = mContext.getResources().getDrawable(mUserSetSelectedIndicatorResId);
+ mUnselectedDrawable = mContext.getResources().getDrawable(mUserSetUnSelectedIndicatorResId);
+
+ redraw();
+ }
+
+ private void redraw(){
+ mPreviousSelectedIndicator = null;
+ for(View i:mIndicators){
+ removeView(i);
+ }
+ for(int i =0 ;i mItemCount){
+ for(int i =0 ; i< count - mItemCount;i++){
+ ImageView indicator = new ImageView(mContext);
+ indicator.setImageDrawable(mUnselectedDrawable);
+ addView(indicator);
+ mIndicators.add(indicator);
+ }
+ }else if(count < mItemCount){
+ for(int i = 0; i < mItemCount - count;i++){
+ removeView(mIndicators.get(0));
+ mIndicators.remove(0);
+ }
+ }
+ mItemCount = count;
+ mPager.setCurrentItem(mItemCount*20 + mPager.getCurrentItem());
+ }
+
+ @Override
+ public void onInvalidated() {
+ super.onInvalidated();
+ }
+ };
+
+ private void setItemAsSelected(int position){
+ if(mPreviousSelectedIndicator != null){
+ mPreviousSelectedIndicator.setImageDrawable(mUnselectedDrawable);
+ }
+ ImageView currentSelected = (ImageView)getChildAt(position + 1);
+ currentSelected.setImageDrawable(mSelectedDrawable);
+ mPreviousSelectedIndicator = currentSelected;
+ mPreviousSelectedPosition = position;
+ }
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ if(mRealItemCount == 0){
+ return;
+ }
+ int n = position % mRealItemCount;
+ setItemAsSelected(n);
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+
+ }
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Infinity/InfinitePagerAdapter.java b/library/src/main/java/com/daimajia/slider/library/Infinity/InfinitePagerAdapter.java
new file mode 100644
index 0000000..e1ccc53
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Infinity/InfinitePagerAdapter.java
@@ -0,0 +1,108 @@
+package com.daimajia.slider.library.Infinity;
+
+import android.os.Parcelable;
+import android.support.v4.view.PagerAdapter;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.daimajia.slider.library.SliderAdapter;
+
+/**
+ * A PagerAdapter that wraps around another PagerAdapter to handle paging wrap-around.
+ * Thanks to: https://github.com/antonyt/InfiniteViewPager
+ */
+public class InfinitePagerAdapter extends PagerAdapter {
+
+ private static final String TAG = "InfinitePagerAdapter";
+ private static final boolean DEBUG = false;
+
+ private SliderAdapter adapter;
+
+ public InfinitePagerAdapter(SliderAdapter adapter) {
+ this.adapter = adapter;
+ }
+
+ public SliderAdapter getRealAdapter(){
+ return this.adapter;
+ }
+
+ @Override
+ public int getCount() {
+ // warning: scrolling to very high values (1,000,000+) results in
+ // strange drawing behaviour
+ return Integer.MAX_VALUE;
+ }
+
+ /**
+ * @return the {@link #getCount()} result of the wrapped adapter
+ */
+ public int getRealCount() {
+ return adapter.getCount();
+ }
+
+ @Override
+ public Object instantiateItem(ViewGroup container, int position) {
+ if(getRealCount() == 0){
+ return null;
+ }
+ int virtualPosition = position % getRealCount();
+ debug("instantiateItem: real position: " + position);
+ debug("instantiateItem: virtual position: " + virtualPosition);
+
+ // only expose virtual position to the inner adapter
+ return adapter.instantiateItem(container, virtualPosition);
+ }
+
+ @Override
+ public void destroyItem(ViewGroup container, int position, Object object) {
+ if(getRealCount() == 0){
+ return;
+ }
+ int virtualPosition = position % getRealCount();
+ debug("destroyItem: real position: " + position);
+ debug("destroyItem: virtual position: " + virtualPosition);
+
+ // only expose virtual position to the inner adapter
+ adapter.destroyItem(container, virtualPosition, object);
+ }
+
+ /*
+ * Delegate rest of methods directly to the inner adapter.
+ */
+
+ @Override
+ public void finishUpdate(ViewGroup container) {
+ adapter.finishUpdate(container);
+ }
+
+ @Override
+ public boolean isViewFromObject(View view, Object object) {
+ return adapter.isViewFromObject(view, object);
+ }
+
+ @Override
+ public void restoreState(Parcelable bundle, ClassLoader classLoader) {
+ adapter.restoreState(bundle, classLoader);
+ }
+
+ @Override
+ public Parcelable saveState() {
+ return adapter.saveState();
+ }
+
+ @Override
+ public void startUpdate(ViewGroup container) {
+ adapter.startUpdate(container);
+ }
+
+ /*
+ * End delegation
+ */
+
+ private void debug(String message) {
+ if (DEBUG) {
+ Log.d(TAG, message);
+ }
+ }
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/daimajia/slider/library/Infinity/InfiniteViewPager.java b/library/src/main/java/com/daimajia/slider/library/Infinity/InfiniteViewPager.java
new file mode 100644
index 0000000..4cd7448
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Infinity/InfiniteViewPager.java
@@ -0,0 +1,53 @@
+package com.daimajia.slider.library.Infinity;
+
+import android.content.Context;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+
+/**
+ * A {@link ViewPager} that allows pseudo-infinite paging with a wrap-around effect. Should be used with an {@link
+ * InfinitePagerAdapter}.
+ */
+public class InfiniteViewPager extends ViewPager {
+
+ public InfiniteViewPager(Context context) {
+ super(context);
+ }
+
+ public InfiniteViewPager(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void setAdapter(PagerAdapter adapter) {
+ super.setAdapter(adapter);
+ // offset first element so that we can scroll to the left
+ setCurrentItem(0);
+ }
+
+ @Override
+ public void setCurrentItem(int item) {
+ // offset the current item to ensure there is space to scroll
+ item = getOffsetAmount() + (item % getAdapter().getCount());
+ super.setCurrentItem(item);
+
+ }
+ public void nextItem(){
+ super.setCurrentItem(getCurrentItem() + 1);
+ }
+
+ private int getOffsetAmount() {
+ if (getAdapter() instanceof InfinitePagerAdapter) {
+ InfinitePagerAdapter infAdapter = (InfinitePagerAdapter) getAdapter();
+ // allow for 100 back cycles from the beginning
+ // should be enough to create an illusion of infinity
+ // warning: scrolling to very high values (1,000,000+) results in
+ // strange drawing behaviour
+ return infAdapter.getRealCount() * 100;
+ } else {
+ return 0;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/daimajia/slider/library/RenderTypes/BaseSliderView.java b/library/src/main/java/com/daimajia/slider/library/RenderTypes/BaseSliderView.java
new file mode 100644
index 0000000..13a42f9
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/RenderTypes/BaseSliderView.java
@@ -0,0 +1,254 @@
+package com.daimajia.slider.library.RenderTypes;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.daimajia.slider.library.R;
+import com.squareup.picasso.Callback;
+import com.squareup.picasso.Picasso;
+import com.squareup.picasso.RequestCreator;
+
+import java.io.File;
+
+/**
+ * Created by daimajia on 14-5-27.
+ */
+public abstract class BaseSliderView {
+
+ protected Context mContext;
+
+ private Bundle mBundle;
+
+ private int mErrorPlaceHolderRes;
+ private int mEmptyPlaceHolderRes;
+
+ private String mUrl;
+ private File mFile;
+ private int mRes;
+
+ protected OnSliderClickListener mOnSliderClickListener;
+
+ private boolean mErrorDisappear;
+
+ private ImageLoadListener mLoadListener;
+
+ private String mDescription;
+
+ protected BaseSliderView(Context context) {
+ mContext = context;
+ this.mBundle = new Bundle();
+ }
+
+ /**
+ * the placeholder image when loading image from url or file.
+ * @param resId Image resource id
+ * @return
+ */
+ public BaseSliderView empty(int resId){
+ mEmptyPlaceHolderRes = resId;
+ return this;
+ }
+
+ /**
+ * determine whether remove the image which failed to download or load from file
+ * @param disappear
+ * @return
+ */
+ public BaseSliderView errorDisappear(boolean disappear){
+ mErrorDisappear = disappear;
+ return this;
+ }
+
+ /**
+ * if you set errorDisappear false, this will set a error placeholder image.
+ * @param resId image resource id
+ * @return
+ */
+ public BaseSliderView error(int resId){
+ mErrorPlaceHolderRes = resId;
+ return this;
+ }
+
+ /**
+ * the description of a slider image.
+ * @param description
+ * @return
+ */
+ public BaseSliderView description(String description){
+ mDescription = description;
+ return this;
+ }
+
+ /**
+ * set a url as a image that preparing to load
+ * @param url
+ * @return
+ */
+ public BaseSliderView image(String url){
+ if(mFile != null || mRes != 0){
+ throw new IllegalStateException("Call multi image function," +
+ "you only have permission to call it once");
+ }
+ mUrl = url;
+ return this;
+ }
+
+ /**
+ * set a file as a image that will to load
+ * @param file
+ * @return
+ */
+ public BaseSliderView image(File file){
+ if(mUrl != null || mRes != 0){
+ throw new IllegalStateException("Call multi image function," +
+ "you only have permission to call it once");
+ }
+ mFile = file;
+ return this;
+ }
+
+ public BaseSliderView image(int res){
+ if(mUrl != null || mFile != null){
+ throw new IllegalStateException("Call multi image function," +
+ "you only have permission to call it once");
+ }
+ mRes = res;
+ return this;
+ }
+
+ public String getUrl(){
+ return mUrl;
+ }
+
+ public boolean isErrorDisappear(){
+ return mErrorDisappear;
+ }
+
+ public int getEmpty(){
+ return mEmptyPlaceHolderRes;
+ }
+
+ public int getError(){
+ return mErrorPlaceHolderRes;
+ }
+
+ public String getDescription(){
+ return mDescription;
+ }
+
+ public Context getContext(){
+ return mContext;
+ }
+
+ /**
+ * set a slider image click listener
+ * @param l
+ * @return
+ */
+ public BaseSliderView setOnSliderClickListener(OnSliderClickListener l){
+ mOnSliderClickListener = l;
+ return this;
+ }
+
+ /**
+ * when you want to extends this class, please use this method to load a image to a imageview.
+ * @param targetImageView
+ */
+ protected void loadImage(ImageView targetImageView){
+ final BaseSliderView me = this;
+
+ mLoadListener.onStart(me);
+
+ Picasso p = Picasso.with(mContext);
+ RequestCreator rq = null;
+ if(mUrl!=null){
+ rq = p.load(mUrl);
+ }else if(mFile != null){
+ rq = p.load(mFile);
+ }else if(mRes != 0){
+ rq = p.load(mRes);
+ }else{
+ return;
+ }
+
+ if(rq == null){
+ return;
+ }
+
+ if(getEmpty() != 0){
+ rq.placeholder(getEmpty());
+ }
+
+ if(getError() != 0){
+ rq.error(getError());
+ }
+ rq.fit();
+
+ rq.into(targetImageView,new Callback() {
+ @Override
+ public void onSuccess() {
+ if(bar!=null)
+ bar.setVisibility(View.INVISIBLE);
+ }
+
+ @Override
+ public void onError() {
+ if(mLoadListener != null){
+ mLoadListener.onEnd(false,me);
+ }
+ }
+ });
+ }
+ View bar = null;
+ /**
+ * when you want to extends this class, you must call this method to bind click event to your view.
+ * @param v
+ */
+ protected void bindClickEvent(View v){
+ final BaseSliderView me = this;
+ bar = v.findViewById(R.id.loading_bar);
+ v.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if(mOnSliderClickListener != null){
+ mOnSliderClickListener.onSliderClick(me);
+ }
+ }
+ });
+ }
+
+ /**
+ * the extended class have to implement getView(), which is called by the adapter,
+ * every extended class response to render their own view.
+ * @return
+ */
+ public abstract View getView();
+
+ /**
+ * set a listener to get a message , if load error.
+ * @param l
+ */
+ public void setOnImageLoadListener(ImageLoadListener l){
+ mLoadListener = l;
+ }
+
+ public interface OnSliderClickListener {
+ public void onSliderClick(BaseSliderView slider);
+ }
+
+ /**
+ * when you have some extra information, please put it in this bundle.
+ * @return
+ */
+ public Bundle getBundle(){
+ return mBundle;
+ }
+
+ public interface ImageLoadListener{
+ public void onStart(BaseSliderView target);
+ public void onEnd(boolean result,BaseSliderView target);
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/RenderTypes/DefaultSliderView.java b/library/src/main/java/com/daimajia/slider/library/RenderTypes/DefaultSliderView.java
new file mode 100644
index 0000000..8ec607d
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/RenderTypes/DefaultSliderView.java
@@ -0,0 +1,31 @@
+package com.daimajia.slider.library.RenderTypes;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.daimajia.slider.library.R;
+
+/**
+ * a simple slider view, which just show a image. If you want to make your own slider view,
+ *
+ * just extend BaseSliderView, and implement getView() method.
+ */
+public class DefaultSliderView extends BaseSliderView{
+
+ public DefaultSliderView(Context context) {
+ super(context);
+ }
+
+ @Override
+ public View getView() {
+ View v = LayoutInflater.from(getContext()).inflate(R.layout.slider_layout_default,null);
+ ImageView target = (ImageView)v.findViewById(R.id.daimajia_slider_image);
+
+ loadImage(target);
+ bindClickEvent(v);
+
+ return v;
+ }
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/RenderTypes/TextSliderView.java b/library/src/main/java/com/daimajia/slider/library/RenderTypes/TextSliderView.java
new file mode 100644
index 0000000..81e8c98
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/RenderTypes/TextSliderView.java
@@ -0,0 +1,29 @@
+package com.daimajia.slider.library.RenderTypes;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.daimajia.slider.library.R;
+
+/**
+ * Created by daimajia on 14-5-28.
+ */
+public class TextSliderView extends BaseSliderView{
+ public TextSliderView(Context context) {
+ super(context);
+ }
+
+ @Override
+ public View getView() {
+ View v = LayoutInflater.from(getContext()).inflate(R.layout.slider_layout_text,null);
+ ImageView target = (ImageView)v.findViewById(R.id.daimajia_slider_image);
+ TextView description = (TextView)v.findViewById(R.id.description);
+ description.setText(getDescription());
+ loadImage(target);
+ bindClickEvent(v);
+ return v;
+ }
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/SliderAdapter.java b/library/src/main/java/com/daimajia/slider/library/SliderAdapter.java
new file mode 100644
index 0000000..9c77d58
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/SliderAdapter.java
@@ -0,0 +1,90 @@
+package com.daimajia.slider.library;
+
+import android.content.Context;
+import android.support.v4.view.PagerAdapter;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.daimajia.slider.library.RenderTypes.BaseSliderView;
+
+import java.util.ArrayList;
+
+/**
+ * Created by daimajia on 14-5-27.
+ */
+public class SliderAdapter extends PagerAdapter implements BaseSliderView.ImageLoadListener{
+
+ private Context mContext;
+ private ArrayList mImageContents;
+
+
+ public SliderAdapter(Context context){
+ mContext = context;
+ mImageContents = new ArrayList();
+ }
+
+ public void addSlider(T slider){
+ slider.setOnImageLoadListener(this);
+ mImageContents.add(slider);
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getItemPosition(Object object) {
+ return POSITION_NONE;
+ }
+
+ public void removeSlider(T slider){
+ if(mImageContents.contains(slider)){
+ mImageContents.remove(slider);
+ notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ public int getCount() {
+ return mImageContents.size();
+ }
+
+ @Override
+ public boolean isViewFromObject(View view, Object object) {
+ return view==object;
+ }
+
+ @Override
+ public void destroyItem(ViewGroup container, int position, Object object) {
+ container.removeView((View) object);
+ }
+
+ @Override
+ public Object instantiateItem(ViewGroup container, int position) {
+ BaseSliderView image = mImageContents.get(position);
+ View v = image.getView();
+ container.addView(v);
+ return v;
+ }
+
+ @Override
+ public void onStart(BaseSliderView target) {
+
+ }
+
+ /**
+ * When image download error, then remove.
+ * @param result
+ * @param target
+ */
+ @Override
+ public void onEnd(boolean result, BaseSliderView target) {
+ if(target.isErrorDisappear() == false || result == true){
+ return;
+ }
+ for (BaseSliderView slider: mImageContents){
+ if(slider.equals(target)){
+ removeSlider(target);
+ break;
+ }
+ }
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/SliderLayout.java b/library/src/main/java/com/daimajia/slider/library/SliderLayout.java
new file mode 100644
index 0000000..17ea20e
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/SliderLayout.java
@@ -0,0 +1,293 @@
+package com.daimajia.slider.library;
+
+import android.content.Context;
+import android.os.Message;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.Interpolator;
+import android.widget.RelativeLayout;
+
+import com.daimajia.slider.library.Indicators.PagerIndicator;
+import com.daimajia.slider.library.Infinity.InfinitePagerAdapter;
+import com.daimajia.slider.library.Infinity.InfiniteViewPager;
+import com.daimajia.slider.library.RenderTypes.BaseSliderView;
+import com.daimajia.slider.library.Transformers.AccordionTransformer;
+import com.daimajia.slider.library.Transformers.BackgroundToForegroundTransformer;
+import com.daimajia.slider.library.Transformers.CubeInTransformer;
+import com.daimajia.slider.library.Transformers.DefaultTransformer;
+import com.daimajia.slider.library.Transformers.DepthPageTransformer;
+import com.daimajia.slider.library.Transformers.FadeTransformer;
+import com.daimajia.slider.library.Transformers.FlipHorizontalTransformer;
+import com.daimajia.slider.library.Transformers.FlipPageViewTransformer;
+import com.daimajia.slider.library.Transformers.ForegroundToBackgroundTransformer;
+import com.daimajia.slider.library.Transformers.RotateDownTransformer;
+import com.daimajia.slider.library.Transformers.RotateUpTransformer;
+import com.daimajia.slider.library.Transformers.StackTransformer;
+import com.daimajia.slider.library.Transformers.TabletTransformer;
+import com.daimajia.slider.library.Transformers.ZoomInTransformer;
+import com.daimajia.slider.library.Transformers.ZoomOutSlideTransformer;
+import com.daimajia.slider.library.Transformers.ZoomOutTransformer;
+import com.daimajia.slider.library.Utils.FixedSpeedScroller;
+
+import java.lang.reflect.Field;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * Created by daimajia on 14-5-27.
+ */
+public class SliderLayout extends RelativeLayout{
+
+ private Context mContext;
+ private InfiniteViewPager mViewPager;
+ private SliderAdapter mSliderAdapter;
+ private PagerIndicator mIndicator;
+
+ private Timer mCycleTimer;
+ private TimerTask mCycleTask;
+
+ private Timer mResumingTimer;
+ private TimerTask mResumingTask;
+
+ private boolean mCycling;
+ private boolean mAutoRecover;
+
+ public SliderLayout(Context context) {
+ this(context,null);
+ }
+
+ public SliderLayout(Context context, AttributeSet attrs) {
+ this(context,attrs,R.attr.imageSliderStyle);
+ }
+
+ public SliderLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mContext = context;
+ LayoutInflater.from(context).inflate(R.layout.slider_layout, this, true);
+ mSliderAdapter = new SliderAdapter(mContext);
+ PagerAdapter wrappedAdapter = new InfinitePagerAdapter(mSliderAdapter);
+
+ mViewPager = (InfiniteViewPager)findViewById(R.id.daimajia_slider_viewpager);
+ mViewPager.setAdapter(wrappedAdapter);
+
+ mIndicator = (PagerIndicator)findViewById(R.id.daimajia_slider_indicator);
+ mIndicator.setViewPager(mViewPager);
+
+ mViewPager.setOnTouchListener(new OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ int action = event.getAction();
+ switch (action) {
+ case MotionEvent.ACTION_UP:
+ recoverCycle();
+ break;
+ }
+ return false;
+ }
+ });
+ setSliderTransformDuration(1100,null);
+ }
+
+
+ public void addSlider(T imageContent){
+ mSliderAdapter.addSlider(imageContent);
+ }
+
+ public void startCycle(){
+ startCycle(1000,3400,true);
+ }
+
+ public void startCycle(long delay,long period,boolean autoRecover){
+ mCycleTimer = new Timer();
+ mAutoRecover = autoRecover;
+ mCycleTask = new TimerTask() {
+ @Override
+ public void run() {
+ mh.sendEmptyMessage(0);
+ }
+ };
+ mCycleTimer.schedule(mCycleTask,delay,period);
+ mCycling = true;
+ }
+
+ private void pauseCycle(){
+ if(mCycling){
+ mCycleTimer.cancel();
+ mCycleTask.cancel();
+ mCycling = false;
+ }else{
+ if(mResumingTimer != null && mResumingTask != null){
+ recoverCycle();
+ }
+ }
+ }
+
+ private void recoverCycle(){
+
+ if(!mAutoRecover){
+ return;
+ }
+
+ if(!mCycling){
+ if(mResumingTask != null && mResumingTimer!= null){
+ mResumingTimer.cancel();
+ mResumingTask.cancel();
+ }
+ mResumingTimer = new Timer();
+ mResumingTask = new TimerTask() {
+ @Override
+ public void run() {
+ startCycle();
+ }
+ };
+ mResumingTimer.schedule(mResumingTask,6000);
+ }
+ }
+
+ private android.os.Handler mh = new android.os.Handler(){
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ mViewPager.nextItem();
+ }
+ };
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ int action = ev.getAction();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ pauseCycle();
+ break;
+ }
+ return false;
+ }
+
+
+ public void setIndicatorStyle(int selectedDrawable,int unselectedDrawable){
+ mIndicator.setIndicator(selectedDrawable,unselectedDrawable);
+ }
+
+ public void setPagerTransformer(boolean reverseDrawingOrder, ViewPager.PageTransformer transformer){
+ mViewPager.setPageTransformer(reverseDrawingOrder,transformer);
+ }
+
+ public void setSliderTransformDuration(int period,Interpolator interpolator){
+ try{
+ Field mScroller = ViewPager.class.getDeclaredField("mScroller");
+ mScroller.setAccessible(true);
+ FixedSpeedScroller scroller = new FixedSpeedScroller(mViewPager.getContext(),interpolator, period);
+ mScroller.set(mViewPager,scroller);
+ }catch (Exception e){
+
+ }
+ }
+ public enum Transformer{
+ Default("Default"),
+ Accordion("Accordion"),
+ Background2Foreground("Background2Foreground"),
+ CubeIn("CubeIn"),
+ DepthPage("DepthPage"),
+ Fade("Fade"),
+ FlipHorizontal("FlipHorizontal"),
+ FlipPage("FlipPage"),
+ Foreground2Background("Foreground2Background"),
+ RotateDown("RotateDown"),
+ RotateUp("RotateUp"),
+ Stack("Stack"),
+ Tablet("Tablet"),
+ ZoomIn("ZoomIn"),
+ ZoomOutSlide("ZoomOutSlide"),
+ ZoomOut("ZoomOut");
+
+ private final String name;
+
+ private Transformer(String s){
+ name = s;
+ }
+ public String toString(){
+ return name;
+ }
+
+ public boolean equals(String other){
+ return (other == null)? false:name.equals(other);
+ }
+ };
+
+ public void setPresetTransformer(String transformerName){
+ for(Transformer t : Transformer.values()){
+ if(t.equals(transformerName)){
+ setPresetTransformer(t);
+ return;
+ }
+ }
+ }
+
+ /**
+ * pretty much right? enjoy it. :-D
+ *
+ * @param ts
+ */
+ public void setPresetTransformer(Transformer ts){
+ //
+ // special thanks to https://github.com/ToxicBakery/ViewPagerTransforms
+ //
+
+ ViewPager.PageTransformer t = null;
+ switch (ts){
+ case Default:
+ t = new DefaultTransformer();
+ break;
+ case Accordion:
+ t = new AccordionTransformer();
+ break;
+ case Background2Foreground:
+ t = new BackgroundToForegroundTransformer();
+ break;
+ case CubeIn:
+ t = new CubeInTransformer();
+ break;
+ case DepthPage:
+ t = new DepthPageTransformer();
+ break;
+ case Fade:
+ t = new FadeTransformer();
+ break;
+ case FlipHorizontal:
+ t = new FlipHorizontalTransformer();
+ break;
+ case FlipPage:
+ t = new FlipPageViewTransformer();
+ break;
+ case Foreground2Background:
+ t = new ForegroundToBackgroundTransformer();
+ break;
+ case RotateDown:
+ t = new RotateDownTransformer();
+ break;
+ case RotateUp:
+ t = new RotateUpTransformer();
+ break;
+ case Stack:
+ t = new StackTransformer();
+ break;
+ case Tablet:
+ t = new TabletTransformer();
+ break;
+ case ZoomIn:
+ t = new ZoomInTransformer();
+ break;
+ case ZoomOutSlide:
+ t = new ZoomOutSlideTransformer();
+ break;
+ case ZoomOut:
+ t = new ZoomOutTransformer();
+ break;
+ }
+ setPagerTransformer(true,t);
+ }
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/ABaseTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/ABaseTransformer.java
new file mode 100644
index 0000000..e1a5814
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/ABaseTransformer.java
@@ -0,0 +1,79 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+import android.support.v4.view.ViewPager.PageTransformer;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public abstract class ABaseTransformer implements PageTransformer {
+
+ /**
+ * Called each {@link #transformPage(View, float)}.
+ *
+ * @param view
+ * @param position
+ */
+ protected abstract void onTransform(View view, float position);
+
+ @Override
+ public void transformPage(View view, float position) {
+ onPreTransform(view, position);
+ onTransform(view, position);
+ onPostTransform(view, position);
+ }
+
+ /**
+ * If the position offset of a fragment is less than negative one or greater than one, returning true will set the
+ * visibility of the fragment to {@link View#GONE}. Returning false will force the fragment to {@link View#VISIBLE}.
+ *
+ * @return
+ */
+ protected boolean hideOffscreenPages() {
+ return true;
+ }
+
+ /**
+ * Indicates if the default animations of the view pager should be used.
+ *
+ * @return
+ */
+ protected boolean isPagingEnabled() {
+ return false;
+ }
+
+ /**
+ * Called each {@link #transformPage(View, float)} before {{@link #onTransform(View, float)} is called.
+ *
+ * @param view
+ * @param position
+ */
+ protected void onPreTransform(View view, float position) {
+ final float width = view.getWidth();
+
+ ViewHelper.setRotationX(view,0);
+ ViewHelper.setRotationY(view,0);
+ ViewHelper.setRotation(view,0);
+ ViewHelper.setScaleX(view,1);
+ ViewHelper.setScaleY(view,1);
+ ViewHelper.setPivotX(view,0);
+ ViewHelper.setPivotY(view,0);
+ ViewHelper.setTranslationY(view,0);
+ ViewHelper.setTranslationX(view,isPagingEnabled() ? 0f : -width * position);
+
+ if (hideOffscreenPages()) {
+ ViewHelper.setAlpha(view,position <= -1f || position >= 1f ? 0f : 1f);
+ } else {
+ ViewHelper.setAlpha(view,1f);
+ }
+ }
+
+ /**
+ * Called each {@link #transformPage(View, float)} call after {@link #onTransform(View, float)} is finished.
+ *
+ * @param view
+ * @param position
+ */
+ protected void onPostTransform(View view, float position) {
+ }
+
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/AccordionTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/AccordionTransformer.java
new file mode 100644
index 0000000..411a629
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/AccordionTransformer.java
@@ -0,0 +1,18 @@
+package com.daimajia.slider.library.Transformers;
+
+/**
+ * Created by daimajia on 14-5-29.
+ */
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class AccordionTransformer extends ABaseTransformer {
+
+ @Override
+ protected void onTransform(View view, float position) {
+ ViewHelper.setPivotX(view,position < 0 ? 0 : view.getWidth());
+ ViewHelper.setScaleX(view,position < 0 ? 1f + position : 1f - position);
+ }
+
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/BackgroundToForegroundTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/BackgroundToForegroundTransformer.java
new file mode 100644
index 0000000..b1fb5d6
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/BackgroundToForegroundTransformer.java
@@ -0,0 +1,26 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class BackgroundToForegroundTransformer extends ABaseTransformer {
+
+ @Override
+ protected void onTransform(View view, float position) {
+ final float height = view.getHeight();
+ final float width = view.getWidth();
+ final float scale = min(position < 0 ? 1f : Math.abs(1f - position), 0.5f);
+
+ ViewHelper.setScaleX(view,scale);
+ ViewHelper.setScaleY(view,scale);
+ ViewHelper.setPivotX(view,width*0.5f);
+ ViewHelper.setPivotY(view,height*0.5f);
+ ViewHelper.setTranslationX(view,position < 0 ? width * position : -width * position * 0.25f);
+ }
+
+ private static final float min(float val, float min) {
+ return val < min ? min : val;
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/CubeInTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/CubeInTransformer.java
new file mode 100644
index 0000000..4a74355
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/CubeInTransformer.java
@@ -0,0 +1,22 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class CubeInTransformer extends ABaseTransformer {
+
+ @Override
+ protected void onTransform(View view, float position) {
+ // Rotate the fragment on the left or right edge
+ ViewHelper.setPivotX(view,position > 0 ? 0 : view.getWidth());
+ ViewHelper.setPivotY(view,0);
+ ViewHelper.setRotation(view,-90f * position);
+ }
+
+ @Override
+ public boolean isPagingEnabled() {
+ return true;
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/DefaultTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/DefaultTransformer.java
new file mode 100644
index 0000000..7037092
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/DefaultTransformer.java
@@ -0,0 +1,16 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+
+public class DefaultTransformer extends ABaseTransformer {
+
+ @Override
+ protected void onTransform(View view, float position) {
+ }
+
+ @Override
+ public boolean isPagingEnabled() {
+ return true;
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/DepthPageTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/DepthPageTransformer.java
new file mode 100644
index 0000000..8e3f440
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/DepthPageTransformer.java
@@ -0,0 +1,32 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class DepthPageTransformer extends ABaseTransformer {
+
+ private static final float MIN_SCALE = 0.75f;
+
+ @Override
+ protected void onTransform(View view, float position) {
+ if (position <= 0f) {
+ ViewHelper.setTranslationX(view,0f);
+ ViewHelper.setScaleX(view,1f);
+ ViewHelper.setScaleY(view,1f);
+ } else if (position <= 1f) {
+ final float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
+ ViewHelper.setAlpha(view,1-position);
+ ViewHelper.setPivotY(view,0.5f * view.getHeight());
+ ViewHelper.setTranslationX(view,view.getWidth() * - position);
+ ViewHelper.setScaleX(view,scaleFactor);
+ ViewHelper.setScaleY(view,scaleFactor);
+ }
+ }
+
+ @Override
+ protected boolean isPagingEnabled() {
+ return true;
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/FadeTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/FadeTransformer.java
new file mode 100644
index 0000000..1abac5f
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/FadeTransformer.java
@@ -0,0 +1,34 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.support.v4.view.ViewPager;
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+/**
+ * Created by realandylawton on 11/22/13.
+ */
+public class FadeTransformer implements ViewPager.PageTransformer {
+
+ public void transformPage(View view, float position) {
+
+ // Page is not an immediate sibling, just make transparent
+ if(position < -1 || position > 1) {
+ ViewHelper.setAlpha(view,0.6f);
+ }
+ // Page is sibling to left or right
+ else if (position <= 0 || position <= 1) {
+
+ // Calculate alpha. Position is decimal in [-1,0] or [0,1]
+ float alpha = (position <= 0) ? position + 1 : 1 - position;
+ ViewHelper.setAlpha(view,alpha);
+
+ }
+ // Page is active, make fully visible
+ else if (position == 0) {
+ ViewHelper.setAlpha(view,1);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/FlipHorizontalTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/FlipHorizontalTransformer.java
new file mode 100644
index 0000000..c8402e5
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/FlipHorizontalTransformer.java
@@ -0,0 +1,18 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class FlipHorizontalTransformer extends ABaseTransformer {
+
+ @Override
+ protected void onTransform(View view, float position) {
+ final float rotation = 180f * position;
+ ViewHelper.setAlpha(view,rotation > 90f || rotation < -90f ? 0 : 1);
+ ViewHelper.setPivotY(view,view.getHeight()*0.5f);
+ ViewHelper.setPivotX(view,view.getWidth() * 0.5f);
+ ViewHelper.setRotationY(view,rotation);
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/FlipPageViewTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/FlipPageViewTransformer.java
new file mode 100644
index 0000000..8df4620
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/FlipPageViewTransformer.java
@@ -0,0 +1,48 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.os.Build;
+import android.support.v4.view.ViewPager;
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class FlipPageViewTransformer implements ViewPager.PageTransformer {
+ @Override
+ public void transformPage(View view, float position) {
+ float percentage = 1 - Math.abs(position);
+ if(Build.VERSION.SDK_INT >= 13){
+ view.setCameraDistance(12000);
+ }
+ setVisibility(view, position);
+ setTranslation(view);
+ setSize(view, position, percentage);
+ setRotation(view, position, percentage);
+ }
+
+ private void setVisibility(View page, float position) {
+ if (position < 0.5 && position > -0.5) {
+ page.setVisibility(View.VISIBLE);
+ } else {
+ page.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ private void setTranslation(View view) {
+ ViewPager viewPager = (ViewPager) view.getParent();
+ int scroll = viewPager.getScrollX() - view.getLeft();
+ ViewHelper.setTranslationX(view,scroll);
+ }
+
+ private void setSize(View view, float position, float percentage) {
+ ViewHelper.setScaleX(view,(position != 0 && position != 1) ? percentage : 1);
+ ViewHelper.setScaleY(view,(position != 0 && position != 1) ? percentage : 1);
+ }
+
+ private void setRotation(View view, float position, float percentage) {
+ if (position > 0) {
+ ViewHelper.setRotationY(view,-180 * (percentage + 1));
+ } else {
+ ViewHelper.setRotationY(view,180 * (percentage + 1));
+ }
+ }
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/ForegroundToBackgroundTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/ForegroundToBackgroundTransformer.java
new file mode 100644
index 0000000..92f7b23
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/ForegroundToBackgroundTransformer.java
@@ -0,0 +1,26 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class ForegroundToBackgroundTransformer extends ABaseTransformer {
+
+ @Override
+ protected void onTransform(View view, float position) {
+ final float height = view.getHeight();
+ final float width = view.getWidth();
+ final float scale = min(position > 0 ? 1f : Math.abs(1f + position), 0.5f);
+
+ ViewHelper.setScaleX(view,scale);
+ ViewHelper.setScaleY(view,scale);
+ ViewHelper.setPivotX(view,width * 0.5f);
+ ViewHelper.setPivotY(view,height * 0.5f);
+ ViewHelper.setTranslationX(view,position > 0 ? width * position : -width * position * 0.25f);
+ }
+
+ private static final float min(float val, float min) {
+ return val < min ? min : val;
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/RotateDownTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/RotateDownTransformer.java
new file mode 100644
index 0000000..f4ce98a
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/RotateDownTransformer.java
@@ -0,0 +1,27 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class RotateDownTransformer extends ABaseTransformer {
+
+ private static final float ROT_MOD = -15f;
+
+ @Override
+ protected void onTransform(View view, float position) {
+ final float width = view.getWidth();
+ final float height = view.getHeight();
+ final float rotation = ROT_MOD * position * -1.25f;
+
+ ViewHelper.setPivotX(view,width * 0.5f);
+ ViewHelper.setPivotY(view,height);
+ ViewHelper.setRotation(view,rotation);
+ }
+
+ @Override
+ protected boolean isPagingEnabled() {
+ return true;
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/RotateUpTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/RotateUpTransformer.java
new file mode 100644
index 0000000..faee6db
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/RotateUpTransformer.java
@@ -0,0 +1,27 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class RotateUpTransformer extends ABaseTransformer {
+
+ private static final float ROT_MOD = -15f;
+
+ @Override
+ protected void onTransform(View view, float position) {
+ final float width = view.getWidth();
+ final float rotation = ROT_MOD * position;
+
+ ViewHelper.setPivotX(view,width * 0.5f);
+ ViewHelper.setPivotY(view,0f);
+ ViewHelper.setTranslationX(view,0f);
+ ViewHelper.setRotation(view,rotation);
+ }
+
+ @Override
+ protected boolean isPagingEnabled() {
+ return true;
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/StackTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/StackTransformer.java
new file mode 100644
index 0000000..bf138b2
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/StackTransformer.java
@@ -0,0 +1,14 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class StackTransformer extends ABaseTransformer {
+
+ @Override
+ protected void onTransform(View view, float position) {
+ ViewHelper.setTranslationX(view,position < 0 ? 0f : -view.getWidth() * position);
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/TabletTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/TabletTransformer.java
new file mode 100644
index 0000000..cb54c58
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/TabletTransformer.java
@@ -0,0 +1,40 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.graphics.Camera;
+import android.graphics.Matrix;
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class TabletTransformer extends ABaseTransformer {
+
+ private static final Matrix OFFSET_MATRIX = new Matrix();
+ private static final Camera OFFSET_CAMERA = new Camera();
+ private static final float[] OFFSET_TEMP_FLOAT = new float[2];
+
+ @Override
+ protected void onTransform(View view, float position) {
+ final float rotation = (position < 0 ? 30f : -30f) * Math.abs(position);
+
+ ViewHelper.setTranslationX(view,getOffsetXForRotation(rotation, view.getWidth(), view.getHeight()));
+ ViewHelper.setPivotX(view,view.getWidth() * 0.5f);
+ ViewHelper.setPivotY(view,0);
+ ViewHelper.setRotationY(view,rotation);
+ }
+
+ protected static final float getOffsetXForRotation(float degrees, int width, int height) {
+ OFFSET_MATRIX.reset();
+ OFFSET_CAMERA.save();
+ OFFSET_CAMERA.rotateY(Math.abs(degrees));
+ OFFSET_CAMERA.getMatrix(OFFSET_MATRIX);
+ OFFSET_CAMERA.restore();
+
+ OFFSET_MATRIX.preTranslate(-width * 0.5f, -height * 0.5f);
+ OFFSET_MATRIX.postTranslate(width * 0.5f, height * 0.5f);
+ OFFSET_TEMP_FLOAT[0] = width;
+ OFFSET_TEMP_FLOAT[1] = height;
+ OFFSET_MATRIX.mapPoints(OFFSET_TEMP_FLOAT);
+ return (width - OFFSET_TEMP_FLOAT[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/ZoomInTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/ZoomInTransformer.java
new file mode 100644
index 0000000..0839716
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/ZoomInTransformer.java
@@ -0,0 +1,19 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class ZoomInTransformer extends ABaseTransformer {
+
+ @Override
+ protected void onTransform(View view, float position) {
+ final float scale = position < 0 ? position + 1f : Math.abs(1f - position);
+ ViewHelper.setScaleX(view,scale);
+ ViewHelper.setScaleY(view,scale);
+ ViewHelper.setPivotX(view,view.getWidth() * 0.5f);
+ ViewHelper.setPivotY(view,view.getHeight() * 0.5f);
+ ViewHelper.setAlpha(view,position < -1f || position > 1f ? 0f : 1f - (scale - 1f));
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/ZoomOutSlideTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/ZoomOutSlideTransformer.java
new file mode 100644
index 0000000..9cbdeb0
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/ZoomOutSlideTransformer.java
@@ -0,0 +1,40 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class ZoomOutSlideTransformer extends ABaseTransformer {
+
+ private static final float MIN_SCALE = 0.85f;
+ private static final float MIN_ALPHA = 0.5f;
+
+ @Override
+ protected void onTransform(View view, float position) {
+ if (position >= -1 || position <= 1) {
+ // Modify the default slide transition to shrink the page as well
+ final float height = view.getHeight();
+ final float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
+ final float vertMargin = height * (1 - scaleFactor) / 2;
+ final float horzMargin = view.getWidth() * (1 - scaleFactor) / 2;
+
+ // Center vertically
+ ViewHelper.setPivotY(view,0.5f * height);
+
+
+ if (position < 0) {
+ ViewHelper.setTranslationX(view,horzMargin - vertMargin / 2);
+ } else {
+ ViewHelper.setTranslationX(view,-horzMargin + vertMargin / 2);
+ }
+
+ // Scale the page down (between MIN_SCALE and 1)
+ ViewHelper.setScaleX(view,scaleFactor);
+ ViewHelper.setScaleY(view,scaleFactor);
+
+ // Fade the page relative to its size.
+ ViewHelper.setAlpha(view,MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
+ }
+ }
+
+}
diff --git a/library/src/main/java/com/daimajia/slider/library/Transformers/ZoomOutTransformer.java b/library/src/main/java/com/daimajia/slider/library/Transformers/ZoomOutTransformer.java
new file mode 100644
index 0000000..101545a
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Transformers/ZoomOutTransformer.java
@@ -0,0 +1,23 @@
+package com.daimajia.slider.library.Transformers;
+
+import android.view.View;
+
+import com.nineoldandroids.view.ViewHelper;
+
+public class ZoomOutTransformer extends ABaseTransformer {
+
+ @Override
+ protected void onTransform(View view, float position) {
+ final float scale = 1f + Math.abs(position);
+ ViewHelper.setScaleX(view,scale);
+ ViewHelper.setScaleY(view,scale);
+ ViewHelper.setPivotX(view,view.getWidth() * 0.5f);
+ ViewHelper.setPivotY(view,view.getWidth() * 0.5f);
+ ViewHelper.setAlpha(view,position < -1f || position > 1f ? 0f : 1f - (scale - 1f));
+ if(position < -0.9){
+ //-0.9 to prevent a small bug
+ ViewHelper.setTranslationX(view,view.getWidth() * position);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/daimajia/slider/library/Utils/FixedSpeedScroller.java b/library/src/main/java/com/daimajia/slider/library/Utils/FixedSpeedScroller.java
new file mode 100644
index 0000000..e5c8cc1
--- /dev/null
+++ b/library/src/main/java/com/daimajia/slider/library/Utils/FixedSpeedScroller.java
@@ -0,0 +1,35 @@
+package com.daimajia.slider.library.Utils;
+
+import android.content.Context;
+import android.view.animation.Interpolator;
+import android.widget.Scroller;
+
+public class FixedSpeedScroller extends Scroller {
+
+ private int mDuration = 1000;
+
+ public FixedSpeedScroller(Context context) {
+ super(context);
+ }
+
+ public FixedSpeedScroller(Context context, Interpolator interpolator) {
+ super(context, interpolator);
+ }
+
+ public FixedSpeedScroller(Context context, Interpolator interpolator, int period){
+ this(context,interpolator);
+ mDuration = period;
+ }
+
+ @Override
+ public void startScroll(int startX, int startY, int dx, int dy, int duration) {
+ // Ignore received duration, use fixed one instead
+ super.startScroll(startX, startY, dx, dy, mDuration);
+ }
+
+ @Override
+ public void startScroll(int startX, int startY, int dx, int dy) {
+ // Ignore received duration, use fixed one instead
+ super.startScroll(startX, startY, dx, dy, mDuration);
+ }
+}
diff --git a/library/src/main/res/drawable-hdpi/circle_common.xml b/library/src/main/res/drawable-hdpi/circle_common.xml
new file mode 100644
index 0000000..5f879f9
--- /dev/null
+++ b/library/src/main/res/drawable-hdpi/circle_common.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/library/src/main/res/drawable-hdpi/circle_common_layer.xml b/library/src/main/res/drawable-hdpi/circle_common_layer.xml
new file mode 100644
index 0000000..4a816be
--- /dev/null
+++ b/library/src/main/res/drawable-hdpi/circle_common_layer.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/res/drawable-hdpi/circle_selected.xml b/library/src/main/res/drawable-hdpi/circle_selected.xml
new file mode 100644
index 0000000..ea1cee2
--- /dev/null
+++ b/library/src/main/res/drawable-hdpi/circle_selected.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/library/src/main/res/drawable-hdpi/circle_selected_layer.xml b/library/src/main/res/drawable-hdpi/circle_selected_layer.xml
new file mode 100644
index 0000000..d4a4aa0
--- /dev/null
+++ b/library/src/main/res/drawable-hdpi/circle_selected_layer.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/res/drawable-hdpi/ic_launcher.png b/library/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
Binary files /dev/null and b/library/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/library/src/main/res/drawable-mdpi/ic_launcher.png b/library/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
Binary files /dev/null and b/library/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/library/src/main/res/drawable-xhdpi/ic_launcher.png b/library/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
Binary files /dev/null and b/library/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/library/src/main/res/drawable-xxhdpi/ic_launcher.png b/library/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4df1894
Binary files /dev/null and b/library/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/library/src/main/res/layout/indicator_layout.xml b/library/src/main/res/layout/indicator_layout.xml
new file mode 100644
index 0000000..708880a
--- /dev/null
+++ b/library/src/main/res/layout/indicator_layout.xml
@@ -0,0 +1,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/res/layout/slider_layout.xml b/library/src/main/res/layout/slider_layout.xml
new file mode 100644
index 0000000..a51bc02
--- /dev/null
+++ b/library/src/main/res/layout/slider_layout.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/res/layout/slider_layout_default.xml b/library/src/main/res/layout/slider_layout_default.xml
new file mode 100644
index 0000000..a817ae4
--- /dev/null
+++ b/library/src/main/res/layout/slider_layout_default.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/res/layout/slider_layout_text.xml b/library/src/main/res/layout/slider_layout_text.xml
new file mode 100644
index 0000000..5db2b86
--- /dev/null
+++ b/library/src/main/res/layout/slider_layout_text.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..2f81ea2
--- /dev/null
+++ b/library/src/main/res/values/attrs.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/src/main/res/values/strings.xml b/library/src/main/res/values/strings.xml
new file mode 100644
index 0000000..8a9d5cc
--- /dev/null
+++ b/library/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Slider
+
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..462ba77
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':demo', ':library'