Repository: bhargavms/PodSLider
Branch: master
Commit: eac152c7be4f
Files: 47
Total size: 66.9 KB
Directory structure:
gitextract_cysai_1j/
├── .gitignore
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── library/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── example/
│ │ └── podslider/
│ │ └── ApplicationTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── bhargavms/
│ │ │ └── podslider/
│ │ │ ├── EaseOutElasticInterpolator.java
│ │ │ ├── OnPodClickListener.java
│ │ │ ├── Pod.java
│ │ │ └── PodSlider.java
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── ic_accessibility_black_24dp.xml
│ │ │ ├── ic_account_circle_black_24dp.xml
│ │ │ └── ic_directions_car_black_24dp.xml
│ │ └── values/
│ │ ├── attrs.xml
│ │ └── strings.xml
│ └── test/
│ └── java/
│ └── com/
│ └── bhargavms/
│ └── podslider/
│ └── ExampleUnitTest.java
├── readme.md
├── sample/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── example/
│ │ └── podslidersample/
│ │ └── ApplicationTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── podslidersample/
│ │ │ ├── BlankFragment.java
│ │ │ ├── BlankFragmentTwo.java
│ │ │ ├── MainActivity.java
│ │ │ └── PagerInteractionActivity.java
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── ic_android_black_24dp.xml
│ │ │ ├── ic_android_black_24dp1.xml
│ │ │ ├── ic_build_black_24dp.xml
│ │ │ └── ic_weekend_black_24dp.xml
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_pager_interaction.xml
│ │ │ ├── fragment_blank.xml
│ │ │ └── fragment_blank_two.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ └── test/
│ └── java/
│ └── com/
│ └── example/
│ └── podslidersample/
│ └── ExampleUnitTest.java
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
.idea
.DS_Store
/build
/captures
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
flatDir {
dirs 'libs'
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-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
================================================
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.github.dcendents.android-maven'
group='com.github.bhargavms'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
minSdkVersion 11
targetSdkVersion 23
versionCode 1
versionName "1.2.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile 'com.android.support:appcompat-v7:23.4.0'
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
}
================================================
FILE: library/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/talview23/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/androidTest/java/com/example/podslider/ApplicationTest.java
================================================
package com.example.podslider;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}
================================================
FILE: library/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bhargavms.podslider">
<application android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true"
>
</application>
</manifest>
================================================
FILE: library/src/main/java/com/bhargavms/podslider/EaseOutElasticInterpolator.java
================================================
package com.bhargavms.podslider;
import android.view.animation.Interpolator;
/**
* An interpolator that eases past the final value then back towards it elastically.
* <p/>
* math taken from link provided in see also section.
*
* @see <a href="https://github.com/greensock/GreenSock-JS/blob/master/src/uncompressed/easing/EasePack.js">Greensock Github</a></a>
*/
public class EaseOutElasticInterpolator implements Interpolator {
private static final float TWO_PI = (float) (2 * Math.PI);
private float p1;
private float p2;
private float p3;
public EaseOutElasticInterpolator(float amplitude, float period) {
p1 = (amplitude >= 1) ? amplitude : 1;
p2 = period <= 0 ? 0.3f : period / (amplitude >= 1 ? amplitude : 1);
p3 = (float) (p2 / TWO_PI * (Math.asin(1 / p1)));
p2 = TWO_PI / p2;
}
@Override
public float getInterpolation(float p) {
return (float) (p1 * Math.pow(2, -10 * p) * Math.sin((p - p3) * p2) + 1);
}
}
================================================
FILE: library/src/main/java/com/bhargavms/podslider/OnPodClickListener.java
================================================
package com.bhargavms.podslider;
public interface OnPodClickListener {
void onPodClick(int position);
}
================================================
FILE: library/src/main/java/com/bhargavms/podslider/Pod.java
================================================
package com.bhargavms.podslider;
import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.text.TextPaint;
import android.view.animation.BounceInterpolator;
import android.view.animation.DecelerateInterpolator;
class Pod {
private int position = 0;
private String centerText;
private float podRadius = 0;
private int podColor = 0;
private int selectedPodColor = Color.WHITE;
private int mainSliderColor = 0;
private float cx = 0;
private float cy = 0;
private boolean selected = false;
private static final float MAX_RADIUS_INCREMENT_FACTOR = 0.3f;
private float radiusIncrementor = MAX_RADIUS_INCREMENT_FACTOR;
private Handler handler;
private Drawable mDrawable;
private Paint podCirclePaint;
private Paint selectedPodPaint;
private Paint selectedPodTextPaint;
private PodSlider parent;
private PodSlider.DrawableSize mDrawableSize;
public Pod(float radius, int color, int mainSliderColor, int selectedPodColor, PodSlider parent) {
this.mainSliderColor = mainSliderColor;
this.podRadius = radius;
this.podColor = color;
this.selectedPodColor = selectedPodColor;
this.parent = parent;
init();
}
public Pod(int mainSliderColor, int color,
int selectedPodColor, PodSlider parent, int position) {
this.mainSliderColor = mainSliderColor;
this.podColor = color;
this.selectedPodColor = selectedPodColor;
this.parent = parent;
this.position = position;
this.centerText = String.valueOf(position + 1);
init();
}
public Pod(int mainSliderColor, int color,
int selectedPodColor, PodSlider parent, int position, String centerText) {
this.mainSliderColor = mainSliderColor;
this.podColor = color;
this.selectedPodColor = selectedPodColor;
this.parent = parent;
this.position = position;
this.centerText = centerText;
init();
}
public void setCenter(float cx, float cy) {
this.cx = cx;
this.cy = cy;
}
public void setCenterText(String centerText) {
this.centerText = centerText;
}
public void setCenterDrawable(Drawable drawable, PodSlider.DrawableSize size) {
this.mDrawable = drawable;
mDrawableSize = size;
}
public int getPosition() {
return position;
}
public float getCenterX() {
return cx;
}
public float getCenterY() {
return cy;
}
public void setPodRadius(float radius) {
this.podRadius = radius;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
private void init() {
handler = new Handler();
podCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
podCirclePaint.setColor(podColor);
podCirclePaint.setShadowLayer(5.5f, 6.0f, 6.0f, Color.BLACK);
podCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE);
selectedPodPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
selectedPodPaint.setColor(selectedPodColor);
selectedPodPaint.setShadowLayer(5.5f, 6.0f, 6.0f, Color.BLACK);
selectedPodPaint.setStyle(Paint.Style.FILL_AND_STROKE);
Paint mainSliderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mainSliderPaint.setColor(mainSliderColor);
mainSliderPaint.setShadowLayer(5.5f, 6.0f, 6.0f, Color.BLACK);
mainSliderPaint.setStyle(Paint.Style.FILL_AND_STROKE);
selectedPodTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
selectedPodTextPaint.setColor(mainSliderColor);
selectedPodTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
selectedPodTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);
selectedPodTextPaint.setTextAlign(Paint.Align.CENTER);
}
public void drawPod(Canvas canvas) {
if (!selected)
canvas.drawCircle(cx, cy, podRadius, podCirclePaint);
else {
canvas.drawCircle(cx, cy, podRadius + (podRadius * radiusIncrementor), selectedPodPaint);
float textSize = (podRadius + MAX_RADIUS_INCREMENT_FACTOR) * 2;
selectedPodTextPaint.setTextSize(textSize);
if (mDrawable == null) {
canvas.drawText(centerText,
cx,
// http://stackoverflow.com/questions/11120392/android-center-text-on-canvas
cy - ((selectedPodTextPaint.descent() + selectedPodTextPaint.ascent()) / 2),
selectedPodTextPaint);
} else {
float diameter;
switch (mDrawableSize) {
case FIT_LARGE_CIRCLE:
diameter = parent.largeCircleRadius * 2;
break;
case FIT_MEDIUM_CIRCLE:
diameter = parent.mediumCircleRadius * 2;
break;
case FIT_POD_CIRCLE:
diameter = (podRadius + MAX_RADIUS_INCREMENT_FACTOR) * 2;
break;
default:
diameter = (podRadius + MAX_RADIUS_INCREMENT_FACTOR) * 2;
}
float squareSideLengthBy2 = (getSquareSideLength(diameter) / 2);
mDrawable.setBounds(
(int) (cx - squareSideLengthBy2),
(int) (cy - squareSideLengthBy2),
(int) (cx + squareSideLengthBy2),
(int) (cy + squareSideLengthBy2)
);
mDrawable.draw(canvas);
}
}
}
private float getSquareSideLength(float radius) {
return (float) Math.sqrt(Math.pow(radius, 2) / 2);
}
public boolean doesCoOrdinatesLieInSelectRange(float x, float y) {
float range = podRadius * (7 / 3);
return x > cx - range && x < cx + range && y > cy - range && y < cy + range;
}
public boolean isSelected() {
return selected;
}
public void animatePod() {
if (!selected)
return;
radiusIncrementor = 0;
// handler.post(new Runnable() {
// @Override
// public void run() {
// if (radiusIncrementor >= MAX_RADIUS_INCREMENT_FACTOR) {
// handler.removeCallbacks(this);
// } else {
// float v = (MAX_RADIUS_INCREMENT_FACTOR - radiusIncrementor) /
// PodSlider.LARGE_CIRCLE_MOVE_TIME_IN_MS;
// radiusIncrementor += v * PodSlider.TIME_FOR_EACH_INCREMENT_IN_MS;
// handler.postDelayed(this, PodSlider.TIME_FOR_EACH_INCREMENT_IN_MS);
// parent.invalidate();
// }
// }
// });
ValueAnimator animator = ValueAnimator.ofFloat(radiusIncrementor, MAX_RADIUS_INCREMENT_FACTOR);
animator.setDuration(PodSlider.ANIMATION_DURATION);
animator.setInterpolator(new DecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
radiusIncrementor = (float) animation.getAnimatedValue();
int left = (int) (cx - podRadius);
int right = (int) (cx + podRadius);
int top = (int) (cy - podRadius);
int bottom = (int) (cy + podRadius);
parent.invalidate(left, top, right, bottom);
}
});
animator.start();
}
}
================================================
FILE: library/src/main/java/com/bhargavms/podslider/PodSlider.java
================================================
package com.bhargavms.podslider;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
import java.lang.ref.WeakReference;
/**
* A view that looks like this http://codepen.io/chrisgannon/pen/mPoMxq
*/
public class PodSlider extends View {
public enum DrawableSize {
FIT_POD_CIRCLE, FIT_MEDIUM_CIRCLE, FIT_LARGE_CIRCLE
}
public static final int ANIMATION_DURATION = 600;
private int numberOfPods;
private Paint mainPaint;
private Pod[] pods;
private OnPodClickListener mPodClickListener;
private int currentlySelectedPod = -1;
private boolean firstDraw = true;
private ViewPager mViewPager;
private boolean isViewMeasured = false;
private int mainSliderColor;
private int podColor;
private int selectedPodColor;
private int mediumCircleColor;
private int largeCircleColor;
private Paint mediumCirclePaint;
private Paint largeCirclePaint;
private float touchStartX;
private float touchStartY;
float largeCircleRadius;
float mediumCircleRadius;
private float largeCircleCurrentCenterX;
private float mediumCircleCurrentCenterX;
private ValueAnimator largeCircleAnimator = null;
private ValueAnimator mediumCircleAnimator = null;
private Interpolator largeCircleInterpolator = null;
private Interpolator mediumCircleInterpolator = null;
private boolean usePageTitle = true;
@SuppressWarnings("FieldCanBeLocal")
private float podRadius;
private ValueAnimator.AnimatorUpdateListener largeCircleAnimatorListener =
new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
updateLargeCircleCenterX(animation);
}
};
private ValueAnimator.AnimatorUpdateListener mediumCircleAnimatorListener =
new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
updateMediumCircleCenterX(animation);
}
};
private Rect clipBounds;
public PodSlider(Context context) {
super(context);
}
public PodSlider(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public PodSlider(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
@TargetApi(21)
public PodSlider(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
}
public void setPodClickListener(OnPodClickListener listener) {
this.mPodClickListener = listener;
}
private void init(Context c, AttributeSet attrs) {
TypedArray a = c.getTheme().obtainStyledAttributes(attrs, R.styleable.PodSlider, 0, 0);
try {
int mainSliderColor = a.getColor(R.styleable.PodSlider_mainSliderColor, 0);
int numberOfPods = a.getInt(R.styleable.PodSlider_numberOfPods, 1);
int podColor = a.getColor(R.styleable.PodSlider_podColor, 0);
int selectedPodColor = a.getColor(R.styleable.PodSlider_selectedPodColor, Color.WHITE);
mediumCircleColor = a.getColor(R.styleable.PodSlider_mediumCircleColor, podColor);
largeCircleColor = a.getColor(R.styleable.PodSlider_largeCircleColor, mainSliderColor);
init(numberOfPods, podColor, mainSliderColor, selectedPodColor);
} finally {
a.recycle();
}
}
@Override
public void setBackgroundColor(int color) {
mainSliderColor = color;
this.mainPaint.setColor(color);
invalidate();
}
public void setNumberOfPods(int numberOfPods) {
this.numberOfPods = numberOfPods;
pods = new Pod[numberOfPods];
for (int i = 0; i < numberOfPods; i++) {
pods[i] = new Pod(mainSliderColor, podColor, selectedPodColor, this, i);
}
if (currentlySelectedPod != -1 && currentlySelectedPod < PodSlider.this.numberOfPods) {
setCurrentlySelectedPod(currentlySelectedPod);
} else {
setCurrentlySelectedPod(0);
}
if (!isViewMeasured) {
return;
}
requestLayout();
}
public void setPodTexts(String[] texts) {
if (texts.length < pods.length) {
throw new IllegalStateException("The length of the texts array must be same " +
"as the number of pods.");
}
for (int i = 0; i < pods.length; i++) {
pods[i].setCenterText(texts[i]);
}
invalidate();
}
public void setPodDrawables(Drawable[] drawables, DrawableSize size) {
if (drawables.length < pods.length)
throw new IllegalStateException("The length of the drawables array must be same " +
"as the number of pods.");
for (int i = 0; i < pods.length; i++) {
pods[i].setCenterDrawable(drawables[i], size);
}
invalidate();
}
private void init(final int numberOfPods, int podColor,
int mainSliderColor, int selectedPodColor) {
this.mainSliderColor = mainSliderColor;
this.podColor = podColor;
this.selectedPodColor = selectedPodColor;
clipBounds = new Rect();
mainPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mainPaint.setColor(mainSliderColor);
mainPaint.setShadowLayer(5.5f, 6.0f, 6.0f, Color.BLACK);
mainPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mediumCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mediumCirclePaint.setColor(mediumCircleColor);
mediumCirclePaint.setShadowLayer(5.5f, 6.0f, 6.0f, Color.BLACK);
mediumCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE);
largeCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
largeCirclePaint.setColor(largeCircleColor);
largeCirclePaint.setShadowLayer(5.5f, 6.0f, 6.0f, Color.BLACK);
largeCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE);
setNumberOfPods(numberOfPods);
currentlySelectedPod = 0;
largeCircleInterpolator = new EaseOutElasticInterpolator(1.0f, 1.9f);
mediumCircleInterpolator = new EaseOutElasticInterpolator(1.0f, 1.3f);
}
/**
* Set the currently selected pod AND also animate the view.
* <p/>
* Please remember to use this only after
* the view has been rendered (i.e donot use this in onCreate()/onCreateView()
* this will cause the large and medium circle to be drawn at (0, height/2)
*
* @param currentlySelectedPod the position of pod you want to be selected.
*/
public void setCurrentlySelectedPodAndAnimate(int currentlySelectedPod) {
setCurrentlySelectedPod(currentlySelectedPod);
update(pods[currentlySelectedPod].getCenterX());
}
/**
* @param interpolator a custom interpolator to interpolate time for large circle animation
*/
@SuppressWarnings("unused")
public void setLargeCircleInterpolator(Interpolator interpolator) {
largeCircleInterpolator = interpolator;
}
/**
* @param interpolator a custom interpolator to interpolate time for medium circle animation.
*/
@SuppressWarnings("unused")
public void setMediumCircleInterpolator(Interpolator interpolator) {
this.mediumCircleInterpolator = interpolator;
}
public void setCurrentlySelectedPod(int currentlySelectedPod) {
this.currentlySelectedPod = currentlySelectedPod;
for (int i = 0; i < numberOfPods; i++) {
pods[i].setSelected(false);
}
pods[currentlySelectedPod].setSelected(true);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction() & MotionEvent.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
touchStartX = event.getX();
touchStartY = event.getY();
return true;
case MotionEvent.ACTION_UP:
float endX = event.getX();
float endY = event.getY();
if (isAClick(touchStartX, endX, touchStartY, endY)) {
onClick(endX, endY);
}
return true;
default:
return false;
}
}
private void onClick(float x, float y) {
for (int i = 0; i < pods.length; i++) {
Pod pod = pods[i];
if (pod.doesCoOrdinatesLieInSelectRange(x, y)) {
setCurrentlySelectedPodAndAnimate(i);
// propagate click.
if (mPodClickListener != null)
this.mPodClickListener.onPodClick(i);
if (mViewPager != null)
mViewPager.setCurrentItem(i);
return;
}
}
}
private void moveMediumCircle(float toX) {
if (mediumCircleAnimator != null && mediumCircleAnimator.isRunning())
mediumCircleAnimator.cancel();
mediumCircleAnimator = ValueAnimator.ofFloat(mediumCircleCurrentCenterX, toX);
mediumCircleAnimator.setDuration(ANIMATION_DURATION);
mediumCircleAnimator.setInterpolator(mediumCircleInterpolator);
mediumCircleAnimator.addUpdateListener(mediumCircleAnimatorListener);
mediumCircleAnimator.start();
}
private void moveLargeCircle(float toX) {
if (largeCircleAnimator != null && largeCircleAnimator.isRunning())
largeCircleAnimator.cancel();
largeCircleAnimator = ValueAnimator.ofFloat(largeCircleCurrentCenterX, toX);
largeCircleAnimator.setDuration(ANIMATION_DURATION);
largeCircleAnimator.setInterpolator(largeCircleInterpolator);
largeCircleAnimator.addUpdateListener(largeCircleAnimatorListener);
largeCircleAnimator.start();
}
private void updateLargeCircleCenterX(ValueAnimator animator) {
largeCircleCurrentCenterX = (float) animator.getAnimatedValue();
invalidateOnlyRectIfPossible();
}
private void invalidateOnlyRectIfPossible() {
if (clipBounds != null && clipBounds.left != 0 &&
clipBounds.top != 0 && clipBounds.right != 0 && clipBounds.bottom != 0)
invalidate(clipBounds);
else
invalidate();
}
private void updateMediumCircleCenterX(ValueAnimator animator) {
mediumCircleCurrentCenterX = (float) animator.getAnimatedValue();
invalidateOnlyRectIfPossible();
}
private void update(float toX) {
pods[currentlySelectedPod].animatePod();
moveLargeCircle(toX);
moveMediumCircle(toX);
}
public void usePageTitles(boolean usePageTitle) {
this.usePageTitle = usePageTitle;
}
public void setUpWithViewPager(ViewPager pager) {
mViewPager = pager;
final PagerAdapter adapter = pager.getAdapter();
if (adapter == null) {
throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
}
setNumberOfPods(adapter.getCount());
if (usePageTitle) {
for (int i = 0; i < pods.length; i++) {
String pageTitle = adapter.getPageTitle(i) != null ?
adapter.getPageTitle(i).toString() : null;
if (pageTitle != null)
pods[i].setCenterText(pageTitle);
}
}
pager.addOnPageChangeListener(new PodSliderOnPageChangeListener(this));
if (adapter.getCount() > 0) {
final int curItem = pager.getCurrentItem();
if (currentlySelectedPod != curItem) {
currentlySelectedPod = curItem;
}
}
}
//
// public Pod getPod(int position) {
// if (pods == null) {
// throw new IllegalStateException("You need to init the pods first by calling " +
// "setNumberOfPods() or setUpWithViewPager");
// }
// if (position >= pods.length || position <= 0) {
// throw new IndexOutOfBoundsException("Number of pods is " + pods.length
// + " passed position is " + position);
// }
// return pods[position];
// }
private boolean isAClick(float startX, float endX, float startY, float endY) {
float differenceX = Math.abs(startX - endX);
float differenceY = Math.abs(startY - endY);
return !(differenceX > 5f || differenceY > 5f);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.getClipBounds(clipBounds);
// make large circle diameter equal to the height of the canvas.
largeCircleRadius = Math.min((getHeight() - getPaddingTop() - getPaddingBottom()) / 2,
(getWidth() - getPaddingRight() - getPaddingLeft()) / 2);
mediumCircleRadius = largeCircleRadius / 1.5f;
podRadius = largeCircleRadius * 2 / 7;
float rectangleRight = clipBounds.right - getPaddingRight() - (largeCircleRadius / 5);
float rectangleLeft = clipBounds.left + getPaddingLeft() + (largeCircleRadius / 5);
float rectangleTop = getPaddingTop() + clipBounds.top + (largeCircleRadius / 5);
float rectangleBottom = clipBounds.bottom - getPaddingBottom() - (largeCircleRadius / 5);
drawRoundedRect(canvas, rectangleLeft, rectangleTop, rectangleRight, rectangleBottom);
float podCenterY = rectangleTop + ((rectangleBottom - rectangleTop) / 2);
if (numberOfPods == 1) {
// draw one at the center and be done.
float centerX = rectangleLeft + ((rectangleRight - rectangleLeft) / 2);
largeCircleCurrentCenterX = centerX;
mediumCircleCurrentCenterX = centerX;
Pod pod = pods[0];
pod.setCenter(centerX, podCenterY);
pod.setPodRadius(podRadius);
canvas.drawCircle(largeCircleCurrentCenterX, podCenterY, largeCircleRadius, largeCirclePaint);
canvas.drawCircle(mediumCircleCurrentCenterX, podCenterY, mediumCircleRadius, mediumCirclePaint);
pod.drawPod(canvas);
return;
}
// else you start calculation.
float startX = rectangleLeft + (rectangleBottom - rectangleTop) / 2;
float gapBetweenPodCenters = calculateGapBetweenPodCenters(rectangleLeft, rectangleRight,
rectangleTop, rectangleBottom);
if (firstDraw) {
firstDraw = false;
largeCircleCurrentCenterX = startX + currentlySelectedPod * gapBetweenPodCenters;
mediumCircleCurrentCenterX = startX + currentlySelectedPod * gapBetweenPodCenters;
}
canvas.drawCircle(largeCircleCurrentCenterX, podCenterY, largeCircleRadius, largeCirclePaint);
canvas.drawCircle(mediumCircleCurrentCenterX, podCenterY, mediumCircleRadius, mediumCirclePaint);
for (int i = 0, n = numberOfPods; i < n; i++) {
float podCenterX = startX + i * gapBetweenPodCenters;
Pod pod = pods[i];
pod.setPodRadius(podRadius);
pod.setCenter(podCenterX, podCenterY);
pod.drawPod(canvas);
}
}
private float calculateGapBetweenPodCenters(float left, float right, float top, float bottom) {
// The center of leftmost circle is at getHeight() / 2, getHeight() / 2 (by design)
// The center of rightmost circle is at getWidth() - getHeight /2, getHeight / 2 (by design)
// So the distance between these 2 points is the difference is their x-axis co ordinates
// as both have the same y-axis coordinate.
// Which is nothing but (getWidth() - getHeight / 2) - getHeight / 2
// which equal to getWidth() - 2 * getHeight / 2
// which is equal to getWidth() - getHeight()
float distanceBetweenTheCentersOfPodsAtTheEnd = (right - left) - (bottom - top);
// Now to determine the distance between the center of each pod
// I divide the distanceBetweenTheCentersOfPodsAtTheEnd by number of Pods -1
// because distance between one pod starts at the 0th position.
return distanceBetweenTheCentersOfPodsAtTheEnd / (numberOfPods - 1);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
int desiredHeight = (int) (getContext().getResources().getDisplayMetrics().density * 30);
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(desiredHeight, heightSize);
} else {
//Be whatever you want
height = desiredHeight;
}
int desiredWidth = getDesiredWidth(height);
//Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
//Must be this size
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
width = Math.min(desiredWidth, widthSize);
} else {
//Be whatever you want
width = desiredWidth;
}
setMeasuredDimension(width, height);
isViewMeasured = true;
}
private int getDesiredWidth(int height) {
return height * numberOfPods;
}
private void drawRoundedRect(Canvas canvas, float left, float top, float right, float bottom) {
float radius = Math.min((bottom - top) / 2, (right - left) / 2);
canvas.drawCircle(left + radius, top + radius, radius, mainPaint);
canvas.drawCircle(right - radius, top + radius, radius, mainPaint);
canvas.drawRect(left + radius, top, right - radius, bottom, mainPaint);
}
public static class PodSliderOnPageChangeListener implements ViewPager.OnPageChangeListener {
private final WeakReference<PodSlider> mPodSliderRef;
// private int mScrollState;
// private int mPendingSelection = -1;
public PodSliderOnPageChangeListener(PodSlider podSlider) {
mPodSliderRef = new WeakReference<>(podSlider);
}
@Override
public void onPageScrollStateChanged(int state) {
// mScrollState = state;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// final PodSlider podSlider = mPodSliderRef.get();
// if (podSlider == null) {
// return;
// }
/*float currentX = podSlider.largeAndSmallCircleCurrentCenterX;
float differenceX;
if (position == podSlider.currentlySelectedPod) {
differenceX = podSlider.pods[position + 1].getCenterX() - currentX;
podSlider.largeAndSmallCircleCurrentCenterX += differenceX * positionOffset;
} else {
differenceX = podSlider.pods[position - 1].getCenterX() - currentX;
podSlider.largeAndSmallCircleCurrentCenterX -= differenceX * positionOffset;
}
podSlider.invalidate();*/
/*if (mPendingSelection == -1 ||
podSlider.pods[podSlider.currentlySelectedPod].getCenterX() !=
podSlider.pods[mPendingSelection].getCenterX()) {
float currentX = podSlider.largeAndSmallCircleCurrentCenterX;
float differenceX;
if (positionOffset > 0 || mPendingSelection == -1)
differenceX = podSlider.pods[position + 1].getCenterX() - currentX;
else
differenceX = podSlider.pods[mPendingSelection].getCenterX() - currentX;
podSlider.largeAndSmallCircleCurrentCenterX += differenceX * positionOffset;
podSlider.invalidate();
}
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
if (mPendingSelection != -1) {
podSlider.currentlySelectedPod = mPendingSelection;
podSlider.pods[mPendingSelection].animatePod();
mPendingSelection = -1;
}
}*/
/*if (mPendingSelection != -1 && mScrollState == ViewPager.SCROLL_STATE_IDLE) {
podSlider.currentlySelectedPod = mPendingSelection;
podSlider.pods[mPendingSelection].animatePod();
}*/
}
@Override
public void onPageSelected(int position) {
PodSlider podSlider = mPodSliderRef.get();
if (podSlider != null) {
podSlider.setCurrentlySelectedPodAndAnimate(position);
}
}
}
}
================================================
FILE: library/src/main/res/drawable/ic_accessibility_black_24dp.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2c1.1,0 2,0.9 2,2s-0.9,2 -2,2 -2,-0.9 -2,-2 0.9,-2 2,-2zM21,9h-6v13h-2v-6h-2v6L9,22L9,9L3,9L3,7h18v2z"/>
</vector>
================================================
FILE: library/src/main/res/drawable/ic_account_circle_black_24dp.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,5c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM12,19.2c-2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22z"/>
</vector>
================================================
FILE: library/src/main/res/drawable/ic_directions_car_black_24dp.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M18.92,6.01C18.72,5.42 18.16,5 17.5,5h-11c-0.66,0 -1.21,0.42 -1.42,1.01L3,12v8c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1h12v1c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-8l-2.08,-5.99zM6.5,16c-0.83,0 -1.5,-0.67 -1.5,-1.5S5.67,13 6.5,13s1.5,0.67 1.5,1.5S7.33,16 6.5,16zM17.5,16c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM5,11l1.5,-4.5h11L19,11L5,11z"/>
</vector>
================================================
FILE: library/src/main/res/values/attrs.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="PodSlider">
<attr name="mainSliderColor" format="color" />
<attr name="numberOfPods" format="integer" />
<attr name="podColor" format="color" />
<attr name="mediumCircleColor" format="color" />
<attr name="largeCircleColor" format="color" />
<attr name="selectedPodColor" format="color" />
</declare-styleable>
</resources>
================================================
FILE: library/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">PodSlider</string>
</resources>
================================================
FILE: library/src/test/java/com/bhargavms/podslider/ExampleUnitTest.java
================================================
package com.bhargavms.podslider;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* To work on unit tests, switch the Test Artifact in the Build Variants view.
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
================================================
FILE: readme.md
================================================
# PodSlider
----
[](https://android-arsenal.com/details/1/3836)
[](https://jitpack.io/bhargavms/PodSLider)
[](https://github.com/JStumpp/awesome-android)
#### Sample:


## A slider view.
> This project is an attempt to port the svg pod slider created by Chris Gannon to android.
> see [CodePen](http://codepen.io/chrisgannon/pen/mPoMxq)
#### version 1.2.0 Update:
- Major enhancements in how animations are done.
- Added a ease out elastic effect(a wobble effect just before the circles stop).
#### Gradle:
Add it to your project build.gradle with:
```gradle
allprojects {
repositories {
maven { url "https://jitpack.io" }
}
}
```
and to your module's build.gradle dependencies block add the dependency to the library:
> P.S Check Jitpack badge at the top of the readme for the latest version name.
```gradle
dependencies {
compile 'com.github.bhargavms:PodSLider:X.X.X'
}
```
## Usage
#### Xml Attributes
```xml
app:mainSliderColor="@color/mainPodSlider" <!-- the color of the main rounded rectangular bar. -->
app:numberOfPods="2" <!-- the number of small circles (i.e pods) in the slider.-->
app:podColor="#4CAF50" <!-- the color of the pod when its not selected.-->
app:selectedPodColor="#fff" <!-- the color of the pod when its selected.-->
```
#### Setting a click listener
```java
PodSlider podSlider = (PodSlider) findViewById(R.id.pod_slider);
podSlider.setPodClickListener(new OnPodClickListener() {
@Override
public void onPodClick(int position) {
Log.d("PodPosition", "position = " + position);
}
});
```
#### To set Currently selected Pod
```java
podSlider.setCurrentlySelectedPod(1);
// if you want to change selected pod and also animate
// then use the below method, But please remember to use this only after
// the view has been rendered (i.e donot use this in onCreate()/onCreateView()
// this will cause the large and medium circle to be drawn at (0, height/2)
podSlider.setcurrentlySelectedPodAndAnimate(1);
```
#### To set up with a ViewPager
> By default, the widget uses the String returned by the viewpager
> adapter's `getPageTitle(int)` method, to disable it just set
> `pager.usePageTitle(false)` as false, **before setting up with viewPager**
```java
ViewPager pager = (ViewPager) findViewById(R.id.pager);
PodSlider pagerSlider = (PodSlider) findViewById(R.id.pager_slider);
PodPagerAdapter adapter = new PodPagerAdapter(getSupportFragmentManager());
pager.setAdapter(adapter);
pagerSlider.setUpWithViewPager(pager);
```
#### To change the number of pods programatically
```java
podSlider.setNumberOfPods(4);
```
#### To set custom text
```
// Use this after setting number of pods and make sure the length of texts
// array is equal to or greater than `numberOfPods` that you set using `setNumberOfPods()`
podSlider.setPodTexts(new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"});
```
> (ideally use single character don't ever have texts with more than 1 char looks ugly)
#### To set Drawables
```
Drawable access = getResources().getDrawable(R.drawable.ic_accessibility_black_24dp);
Drawable account = getResources().getDrawable(R.drawable.ic_account_circle_black_24dp);
Drawable car = getResources().getDrawable(R.drawable.ic_directions_car_black_24dp);
// Use this after setting number of pods and make sure the length
// of drawables array is equal to or greater than `numberOfPods`
// that you set using `setNumberOfPods()`
podSlider.setPodDrawables(
new Drawable[]{
access, account, car,
access, account, car,
access, account, car,
access
}, PodSlider.DrawableSize.FIT_POD_CIRCLE
);
```
> I have not added (and do not plan to in the near future) support for passing in
> drawable resource Ids, loading the drawable from resource/creating it from bitmaps
> or whatever is left to you, if you want further customization on deciding the
> size of the drawable please open an issue, based on the amount of traction it receives
> I might decide to implement it.
### LICENSE: (Apache 2.0)
```
Copyright [2016] [Bhargav M S]
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.
```
================================================
FILE: sample/.gitignore
================================================
/build
================================================
FILE: sample/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.example.podslidersample"
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.1.3"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':library')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:support-v4:23.4.0'
}
================================================
FILE: sample/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/talview23/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/androidTest/java/com/example/podslidersample/ApplicationTest.java
================================================
package com.example.podslidersample;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}
================================================
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.example.podslidersample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".PagerInteractionActivity">
</activity>
</application>
</manifest>
================================================
FILE: sample/src/main/java/com/example/podslidersample/BlankFragment.java
================================================
package com.example.podslidersample;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A simple {@link Fragment} subclass.
*/
public class BlankFragment extends Fragment {
public BlankFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}
}
================================================
FILE: sample/src/main/java/com/example/podslidersample/BlankFragmentTwo.java
================================================
package com.example.podslidersample;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* A simple {@link Fragment} subclass.
*/
public class BlankFragmentTwo extends Fragment {
public BlankFragmentTwo() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_blank_two, container, false);
}
}
================================================
FILE: sample/src/main/java/com/example/podslidersample/MainActivity.java
================================================
package com.example.podslidersample;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.bhargavms.podslider.OnPodClickListener;
import com.bhargavms.podslider.PodSlider;
public class MainActivity extends AppCompatActivity implements OnPodClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Drawable access = getResources().getDrawable(R.drawable.ic_accessibility_black_24dp);
final Drawable account = getResources().getDrawable(R.drawable.ic_account_circle_black_24dp);
final Drawable car = getResources().getDrawable(R.drawable.ic_directions_car_black_24dp);
final PodSlider podSlider = (PodSlider) findViewById(R.id.pod_slider);
assert podSlider != null;
podSlider.setPodClickListener(new OnPodClickListener() {
@Override
public void onPodClick(int position) {
Log.d("PodPosition", "position = " + position);
}
});
podSlider.setCurrentlySelectedPod(1);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
podSlider.setNumberOfPods(8);
}
}, 5000);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
podSlider.setPodTexts(new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"});
}
}, 10000);
// new Handler().postDelayed(new Runnable() {
// @Override
// public void run() {
// podSlider.setPodDrawables(
// new Drawable[]{
// access, account, car,
// access, account, car,
// access, account, car,
// access
// }, PodSlider.DrawableSize.FIT_POD_CIRCLE
// );
// }
// }, 15000);
// ViewPager pager = (ViewPager) findViewById(R.id.pager);
// PodSlider pagerSlider = (PodSlider) findViewById(R.id.pager_slider);
// PodPagerAdapter adapter = new PodPagerAdapter(getSupportFragmentManager());
// assert pager != null;
// pager.setAdapter(adapter);
// assert pagerSlider != null;
// pagerSlider.setUpWithViewPager(pager);
//// int accentColor = getResources().getColor(R.color.colorAccent);
// Drawable[] drawables = new Drawable[]{
// access, account, car
// };
// pagerSlider.setPodDrawables(drawables, PodSlider.DrawableSize.FIT_MEDIUM_CIRCLE);
}
@Override
public void onPodClick(int position) {
}
private class PodPagerAdapter extends FragmentStatePagerAdapter {
public PodPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return new BlankFragment();
}
@Override
public int getCount() {
return 3;
}
}
}
================================================
FILE: sample/src/main/java/com/example/podslidersample/PagerInteractionActivity.java
================================================
package com.example.podslidersample;
import android.graphics.Color;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.bhargavms.podslider.OnPodClickListener;
import com.bhargavms.podslider.PodSlider;
import java.util.ArrayList;
import java.util.List;
public class PagerInteractionActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pager_interaction);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
final PodSlider pagerSlider = (PodSlider) findViewById(R.id.pager_slider);
List<Fragment> fragments = new ArrayList<>(2);
fragments.add(new BlankFragment());
fragments.add(new BlankFragmentTwo());
List<String> titles = new ArrayList<>(2);
titles.add("A");
titles.add("B");
// final int[] colors = new int[]{
// Color.parseColor("#FFC169"),
// Color.parseColor("#F68C6F")
// };
assert pager != null;
pager.setAdapter(new PagerAdapter(getSupportFragmentManager(), fragments, titles));
assert pagerSlider != null;
pagerSlider.setUpWithViewPager(pager);
// pagerSlider.setPodClickListener(new OnPodClickListener() {
// @Override
// public void onPodClick(int position) {
// pagerSlider.setBackgroundColor(colors[position]);
// }
// });
}
private static class PagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments;
private List<String> titles;
public PagerAdapter(FragmentManager fm,
List<Fragment> fragments, List<String> titles) {
super(fm);
this.fragments = fragments;
this.titles = titles;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
}
}
================================================
FILE: sample/src/main/res/drawable/ic_android_black_24dp.xml
================================================
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportHeight="505.145"
android:viewportWidth="505.145">
<path
android:fillColor="#AB4343"
android:pathData="M68.5,164.7h-1.3c-16.6,0 -30.1,13.6 -30.1,30.1v131.1c0,16.6 13.5,30.1 30.1,30.1h1.3c16.6,0 30.1,-13.6 30.1,-30.1V194.8C98.7,178.3 85.1,164.7 68.5,164.7z" />
<path
android:fillColor="#AB4343"
android:pathData="M113.1,376.5c0,15.2 12.4,27.6 27.7,27.6h29.6v70.8c0,16.6 13.6,30.2 30.1,30.2h1.3c16.6,0 30.2,-13.5 30.2,-30.2v-70.8h41.3v70.8c0,16.6 13.6,30.2 30.2,30.2h1.3c16.6,0 30.1,-13.5 30.1,-30.2v-70.8h29.6c15.2,0 27.7,-12.4 27.7,-27.6V169.5H113.1V376.5z" />
<path
android:fillColor="#AB4343"
android:pathData="M322,44l23.5,-36.3c1.5,-2.3 0.8,-5.4 -1.5,-6.9c-2.3,-1.5 -5.4,-0.9 -6.9,1.5l-24.4,37.5c-18.3,-7.5 -38.7,-11.7 -60.2,-11.7c-21.6,0 -41.9,4.2 -60.2,11.7l-24.3,-37.5c-1.5,-2.4 -4.6,-3 -6.9,-1.5c-2.3,1.5 -3,4.6 -1.5,6.9l23.5,36.3c-42.4,20.8 -71,59.9 -71,104.8c0,2.8 0.2,5.5 0.4,8.2h280.1c0.2,-2.7 0.4,-5.4 0.4,-8.2C393,103.9 364.4,64.8 322,44zM187.7,108.9c-7.4,0 -13.5,-6 -13.5,-13.5c0,-7.5 6,-13.4 13.5,-13.4c7.5,0 13.5,6 13.5,13.4S195.1,108.9 187.7,108.9zM317.5,108.9c-7.4,0 -13.5,-6 -13.5,-13.5c0,-7.5 6,-13.4 13.5,-13.4c7.5,0 13.5,6 13.5,13.4C331,102.9 325,108.9 317.5,108.9z" />
<path
android:fillColor="#AB4343"
android:pathData="M437.9,164.7h-1.3c-16.6,0 -30.2,13.6 -30.2,30.1v131.1c0,16.6 13.6,30.1 30.2,30.1h1.3c16.6,0 30.1,-13.6 30.1,-30.1V194.8C468,178.3 454.5,164.7 437.9,164.7z" />
</vector>
================================================
FILE: sample/src/main/res/drawable/ic_android_black_24dp1.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#F48F63"
android:pathData="M6,18c0,0.55 0.45,1 1,1h1v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L11,19h2v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L16,19h1c0.55,0 1,-0.45 1,-1L18,8L6,8v10zM3.5,8C2.67,8 2,8.67 2,9.5v7c0,0.83 0.67,1.5 1.5,1.5S5,17.33 5,16.5v-7C5,8.67 4.33,8 3.5,8zM20.5,8c-0.83,0 -1.5,0.67 -1.5,1.5v7c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5v-7c0,-0.83 -0.67,-1.5 -1.5,-1.5zM15.53,2.16l1.3,-1.3c0.2,-0.2 0.2,-0.51 0,-0.71 -0.2,-0.2 -0.51,-0.2 -0.71,0l-1.48,1.48C13.85,1.23 12.95,1 12,1c-0.96,0 -1.86,0.23 -2.66,0.63L7.85,0.15c-0.2,-0.2 -0.51,-0.2 -0.71,0 -0.2,0.2 -0.2,0.51 0,0.71l1.31,1.31C6.97,3.26 6,5.01 6,7h12c0,-1.99 -0.97,-3.75 -2.47,-4.84zM10,5L9,5L9,4h1v1zM15,5h-1L14,4h1v1z"/>
</vector>
================================================
FILE: sample/src/main/res/drawable/ic_build_black_24dp.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#AB4343"
android:pathData="M22.7,19l-9.1,-9.1c0.9,-2.3 0.4,-5 -1.5,-6.9 -2,-2 -5,-2.4 -7.4,-1.3L9,6 6,9 1.6,4.7C0.4,7.1 0.9,10.1 2.9,12.1c1.9,1.9 4.6,2.4 6.9,1.5l9.1,9.1c0.4,0.4 1,0.4 1.4,0l2.3,-2.3c0.5,-0.4 0.5,-1.1 0.1,-1.4z"/>
</vector>
================================================
FILE: sample/src/main/res/drawable/ic_weekend_black_24dp.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:pathData="M21,10c-1.1,0 -2,0.9 -2,2v3L5,15v-3c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2v5c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2v-5c0,-1.1 -0.9,-2 -2,-2zM18,5L6,5c-1.1,0 -2,0.9 -2,2v2.15c1.16,0.41 2,1.51 2,2.82L6,14h12v-2.03c0,-1.3 0.84,-2.4 2,-2.82L20,7c0,-1.1 -0.9,-2 -2,-2z"
android:fillColor="#EE8A5E"/>
</vector>
================================================
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"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
android:background="#6DA792"
tools:context="com.example.podslidersample.MainActivity">
<com.bhargavms.podslider.PodSlider
android:id="@+id/pod_slider"
android:layout_width="wrap_content"
android:layout_height="48dp"
app:mainSliderColor="@color/mainPodSlider"
app:numberOfPods="2"
app:podColor="#4CAF50"
app:mediumCircleColor="#4CAF50"
app:selectedPodColor="#fff"
android:layout_marginTop="50dp"/>
<!--<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</android.support.v4.view.ViewPager>
<com.bhargavms.podslider.PodSlider
android:id="@+id/pager_slider"
android:layout_width="wrap_content"
android:layout_height="78dp"
app:mainSliderColor="@color/mainPodSlider"
app:podColor="#4CAF50"
app:mediumCircleColor="#388E3C"
android:layout_gravity="center_horizontal"
app:selectedPodColor="#fff" />-->
</LinearLayout>
================================================
FILE: sample/src/main/res/layout/activity_pager_interaction.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.example.podslidersample.PagerInteractionActivity">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
<com.bhargavms.podslider.PodSlider
android:id="@+id/pager_slider"
app:largeCircleColor="#8C3939"
app:mainSliderColor="#8C3939"
app:mediumCircleColor="#E47657"
android:layout_width="wrap_content"
android:layout_height="72dp"
android:layout_gravity="center|bottom"
android:layout_margin="16dp"
app:podColor="#E47657"/>
</FrameLayout>
================================================
FILE: sample/src/main/res/layout/fragment_blank.xml
================================================
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F68C6F"
tools:context="com.example.podslidersample.BlankFragment">
<ImageView
android:id="@+id/img_android"
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/ic_android_black_24dp"
android:layout_centerInParent="true"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="85dp"
android:layout_height="85dp"
android:src="@drawable/ic_build_black_24dp"
android:layout_toLeftOf="@+id/img_android"
android:layout_centerInParent="true"
android:layout_marginRight="-45dp"/>
</RelativeLayout>
================================================
FILE: sample/src/main/res/layout/fragment_blank_two.xml
================================================
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFC169"
tools:context="com.example.podslidersample.BlankFragmentTwo">
<ImageView
android:id="@+id/img_sofa"
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/ic_weekend_black_24dp"
android:layout_centerInParent="true"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="85dp"
android:layout_height="85dp"
android:src="@drawable/ic_android_black_24dp"
android:layout_centerInParent="true"
android:layout_above="@id/img_sofa"
android:layout_marginBottom="-90dp" />
</RelativeLayout>
================================================
FILE: sample/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="mainPodSlider">#2E7D31</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>
</resources>
================================================
FILE: sample/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">PodSliderSample</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources>
================================================
FILE: sample/src/main/res/values/styles.xml
================================================
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">#6FAA94</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
================================================
FILE: sample/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
================================================
FILE: sample/src/test/java/com/example/podslidersample/ExampleUnitTest.java
================================================
package com.example.podslidersample;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* To work on unit tests, switch the Test Artifact in the Build Variants view.
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
================================================
FILE: settings.gradle
================================================
include ':sample', ':library'
gitextract_cysai_1j/ ├── .gitignore ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── library/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── example/ │ │ └── podslider/ │ │ └── ApplicationTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── bhargavms/ │ │ │ └── podslider/ │ │ │ ├── EaseOutElasticInterpolator.java │ │ │ ├── OnPodClickListener.java │ │ │ ├── Pod.java │ │ │ └── PodSlider.java │ │ └── res/ │ │ ├── drawable/ │ │ │ ├── ic_accessibility_black_24dp.xml │ │ │ ├── ic_account_circle_black_24dp.xml │ │ │ └── ic_directions_car_black_24dp.xml │ │ └── values/ │ │ ├── attrs.xml │ │ └── strings.xml │ └── test/ │ └── java/ │ └── com/ │ └── bhargavms/ │ └── podslider/ │ └── ExampleUnitTest.java ├── readme.md ├── sample/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── example/ │ │ └── podslidersample/ │ │ └── ApplicationTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── podslidersample/ │ │ │ ├── BlankFragment.java │ │ │ ├── BlankFragmentTwo.java │ │ │ ├── MainActivity.java │ │ │ └── PagerInteractionActivity.java │ │ └── res/ │ │ ├── drawable/ │ │ │ ├── ic_android_black_24dp.xml │ │ │ ├── ic_android_black_24dp1.xml │ │ │ ├── ic_build_black_24dp.xml │ │ │ └── ic_weekend_black_24dp.xml │ │ ├── layout/ │ │ │ ├── activity_main.xml │ │ │ ├── activity_pager_interaction.xml │ │ │ ├── fragment_blank.xml │ │ │ └── fragment_blank_two.xml │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── values-w820dp/ │ │ └── dimens.xml │ └── test/ │ └── java/ │ └── com/ │ └── example/ │ └── podslidersample/ │ └── ExampleUnitTest.java └── settings.gradle
SYMBOL INDEX (91 symbols across 12 files)
FILE: library/src/androidTest/java/com/example/podslider/ApplicationTest.java
class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
method ApplicationTest (line 10) | public ApplicationTest() {
FILE: library/src/main/java/com/bhargavms/podslider/EaseOutElasticInterpolator.java
class EaseOutElasticInterpolator (line 12) | public class EaseOutElasticInterpolator implements Interpolator {
method EaseOutElasticInterpolator (line 18) | public EaseOutElasticInterpolator(float amplitude, float period) {
method getInterpolation (line 25) | @Override
FILE: library/src/main/java/com/bhargavms/podslider/OnPodClickListener.java
type OnPodClickListener (line 3) | public interface OnPodClickListener {
method onPodClick (line 4) | void onPodClick(int position);
FILE: library/src/main/java/com/bhargavms/podslider/Pod.java
class Pod (line 14) | class Pod {
method Pod (line 36) | public Pod(float radius, int color, int mainSliderColor, int selectedP...
method Pod (line 45) | public Pod(int mainSliderColor, int color,
method Pod (line 56) | public Pod(int mainSliderColor, int color,
method setCenter (line 67) | public void setCenter(float cx, float cy) {
method setCenterText (line 72) | public void setCenterText(String centerText) {
method setCenterDrawable (line 76) | public void setCenterDrawable(Drawable drawable, PodSlider.DrawableSiz...
method getPosition (line 81) | public int getPosition() {
method getCenterX (line 85) | public float getCenterX() {
method getCenterY (line 89) | public float getCenterY() {
method setPodRadius (line 93) | public void setPodRadius(float radius) {
method setSelected (line 97) | public void setSelected(boolean selected) {
method init (line 101) | private void init() {
method drawPod (line 125) | public void drawPod(Canvas canvas) {
method getSquareSideLength (line 165) | private float getSquareSideLength(float radius) {
method doesCoOrdinatesLieInSelectRange (line 169) | public boolean doesCoOrdinatesLieInSelectRange(float x, float y) {
method isSelected (line 174) | public boolean isSelected() {
method animatePod (line 178) | public void animatePod() {
FILE: library/src/main/java/com/bhargavms/podslider/PodSlider.java
class PodSlider (line 24) | public class PodSlider extends View {
type DrawableSize (line 25) | public enum DrawableSize {
method onAnimationUpdate (line 68) | @Override
method onAnimationUpdate (line 75) | @Override
method PodSlider (line 83) | public PodSlider(Context context) {
method PodSlider (line 87) | public PodSlider(Context context, AttributeSet attrs) {
method PodSlider (line 92) | public PodSlider(Context context, AttributeSet attrs, int defStyleAttr) {
method PodSlider (line 97) | @TargetApi(21)
method setPodClickListener (line 103) | public void setPodClickListener(OnPodClickListener listener) {
method init (line 107) | private void init(Context c, AttributeSet attrs) {
method setBackgroundColor (line 122) | @Override
method setNumberOfPods (line 129) | public void setNumberOfPods(int numberOfPods) {
method setPodTexts (line 146) | public void setPodTexts(String[] texts) {
method setPodDrawables (line 157) | public void setPodDrawables(Drawable[] drawables, DrawableSize size) {
method init (line 167) | private void init(final int numberOfPods, int podColor,
method setCurrentlySelectedPodAndAnimate (line 204) | public void setCurrentlySelectedPodAndAnimate(int currentlySelectedPod) {
method setLargeCircleInterpolator (line 212) | @SuppressWarnings("unused")
method setMediumCircleInterpolator (line 220) | @SuppressWarnings("unused")
method setCurrentlySelectedPod (line 225) | public void setCurrentlySelectedPod(int currentlySelectedPod) {
method onTouchEvent (line 233) | @Override
method onClick (line 253) | private void onClick(float x, float y) {
method moveMediumCircle (line 268) | private void moveMediumCircle(float toX) {
method moveLargeCircle (line 278) | private void moveLargeCircle(float toX) {
method updateLargeCircleCenterX (line 288) | private void updateLargeCircleCenterX(ValueAnimator animator) {
method invalidateOnlyRectIfPossible (line 293) | private void invalidateOnlyRectIfPossible() {
method updateMediumCircleCenterX (line 301) | private void updateMediumCircleCenterX(ValueAnimator animator) {
method update (line 306) | private void update(float toX) {
method usePageTitles (line 312) | public void usePageTitles(boolean usePageTitle) {
method setUpWithViewPager (line 316) | public void setUpWithViewPager(ViewPager pager) {
method isAClick (line 352) | private boolean isAClick(float startX, float endX, float startY, float...
method onDraw (line 358) | @Override
method calculateGapBetweenPodCenters (line 407) | private float calculateGapBetweenPodCenters(float left, float right, f...
method onMeasure (line 422) | @Override
method getDesiredWidth (line 461) | private int getDesiredWidth(int height) {
method drawRoundedRect (line 465) | private void drawRoundedRect(Canvas canvas, float left, float top, flo...
class PodSliderOnPageChangeListener (line 472) | public static class PodSliderOnPageChangeListener implements ViewPager...
method PodSliderOnPageChangeListener (line 477) | public PodSliderOnPageChangeListener(PodSlider podSlider) {
method onPageScrollStateChanged (line 481) | @Override
method onPageScrolled (line 486) | @Override
method onPageSelected (line 528) | @Override
FILE: library/src/test/java/com/bhargavms/podslider/ExampleUnitTest.java
class ExampleUnitTest (line 10) | public class ExampleUnitTest {
method addition_isCorrect (line 11) | @Test
FILE: sample/src/androidTest/java/com/example/podslidersample/ApplicationTest.java
class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
method ApplicationTest (line 10) | public ApplicationTest() {
FILE: sample/src/main/java/com/example/podslidersample/BlankFragment.java
class BlankFragment (line 14) | public class BlankFragment extends Fragment {
method BlankFragment (line 17) | public BlankFragment() {
method onCreateView (line 22) | @Override
FILE: sample/src/main/java/com/example/podslidersample/BlankFragmentTwo.java
class BlankFragmentTwo (line 14) | public class BlankFragmentTwo extends Fragment {
method BlankFragmentTwo (line 17) | public BlankFragmentTwo() {
method onCreateView (line 22) | @Override
FILE: sample/src/main/java/com/example/podslidersample/MainActivity.java
class MainActivity (line 16) | public class MainActivity extends AppCompatActivity implements OnPodClic...
method onCreate (line 18) | @Override
method onPodClick (line 76) | @Override
class PodPagerAdapter (line 81) | private class PodPagerAdapter extends FragmentStatePagerAdapter {
method PodPagerAdapter (line 82) | public PodPagerAdapter(FragmentManager fm) {
method getItem (line 86) | @Override
method getCount (line 91) | @Override
FILE: sample/src/main/java/com/example/podslidersample/PagerInteractionActivity.java
class PagerInteractionActivity (line 17) | public class PagerInteractionActivity extends AppCompatActivity {
method onCreate (line 19) | @Override
class PagerAdapter (line 47) | private static class PagerAdapter extends FragmentStatePagerAdapter {
method PagerAdapter (line 51) | public PagerAdapter(FragmentManager fm,
method getItem (line 58) | @Override
method getCount (line 63) | @Override
method getPageTitle (line 68) | @Override
FILE: sample/src/test/java/com/example/podslidersample/ExampleUnitTest.java
class ExampleUnitTest (line 10) | public class ExampleUnitTest {
method addition_isCorrect (line 11) | @Test
Condensed preview — 47 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (75K chars).
[
{
"path": ".gitignore",
"chars": 65,
"preview": "*.iml\n.gradle\n/local.properties\n.idea\n.DS_Store\n/build\n/captures\n"
},
{
"path": "build.gradle",
"chars": 623,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n r"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 231,
"preview": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "gradle.properties",
"chars": 855,
"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": 655,
"preview": "apply plugin: 'com.android.library'\napply plugin: 'com.github.dcendents.android-maven'\n\ngroup='com.github.bhargavms'\n\nan"
},
{
"path": "library/proguard-rules.pro",
"chars": 658,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /h"
},
{
"path": "library/src/androidTest/java/com/example/podslider/ApplicationTest.java",
"chars": 352,
"preview": "package com.example.podslider;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href"
},
{
"path": "library/src/main/AndroidManifest.xml",
"chars": 264,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.bhargavms.podslider\">\n\n <applic"
},
{
"path": "library/src/main/java/com/bhargavms/podslider/EaseOutElasticInterpolator.java",
"chars": 1001,
"preview": "package com.bhargavms.podslider;\n\nimport android.view.animation.Interpolator;\n\n/**\n * An interpolator that eases past th"
},
{
"path": "library/src/main/java/com/bhargavms/podslider/OnPodClickListener.java",
"chars": 109,
"preview": "package com.bhargavms.podslider;\n\npublic interface OnPodClickListener {\n void onPodClick(int position);\n}\n"
},
{
"path": "library/src/main/java/com/bhargavms/podslider/Pod.java",
"chars": 7843,
"preview": "package com.bhargavms.podslider;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Canvas;\nimport android"
},
{
"path": "library/src/main/java/com/bhargavms/podslider/PodSlider.java",
"chars": 21792,
"preview": "package com.bhargavms.podslider;\n\nimport android.animation.ValueAnimator;\nimport android.annotation.TargetApi;\nimport an"
},
{
"path": "library/src/main/res/drawable/ic_accessibility_black_24dp.xml",
"chars": 395,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\""
},
{
"path": "library/src/main/res/drawable/ic_account_circle_black_24dp.xml",
"chars": 540,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\""
},
{
"path": "library/src/main/res/drawable/ic_directions_car_black_24dp.xml",
"chars": 678,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\""
},
{
"path": "library/src/main/res/values/attrs.xml",
"chars": 455,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <declare-styleable name=\"PodSlider\">\n <attr name=\"mainSlid"
},
{
"path": "library/src/main/res/values/strings.xml",
"chars": 72,
"preview": "<resources>\n <string name=\"app_name\">PodSlider</string>\n</resources>\n"
},
{
"path": "library/src/test/java/com/bhargavms/podslider/ExampleUnitTest.java",
"chars": 316,
"preview": "package com.bhargavms.podslider;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * To work on unit test"
},
{
"path": "readme.md",
"chars": 5036,
"preview": "# PodSlider\n\n----\n[](ht"
},
{
"path": "sample/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "sample/build.gradle",
"chars": 714,
"preview": "apply plugin: 'com.android.application'\n\nandroid {\n compileSdkVersion 23\n buildToolsVersion \"23.0.3\"\n\n defaultC"
},
{
"path": "sample/proguard-rules.pro",
"chars": 658,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /h"
},
{
"path": "sample/src/androidTest/java/com/example/podslidersample/ApplicationTest.java",
"chars": 358,
"preview": "package com.example.podslidersample;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <"
},
{
"path": "sample/src/main/AndroidManifest.xml",
"chars": 748,
"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/example/podslidersample/BlankFragment.java",
"chars": 657,
"preview": "package com.example.podslidersample;\n\n\nimport android.os.Bundle;\nimport android.support.v4.app.Fragment;\nimport android."
},
{
"path": "sample/src/main/java/com/example/podslidersample/BlankFragmentTwo.java",
"chars": 650,
"preview": "package com.example.podslidersample;\n\n\nimport android.os.Bundle;\nimport android.support.v4.app.Fragment;\nimport android."
},
{
"path": "sample/src/main/java/com/example/podslidersample/MainActivity.java",
"chars": 3476,
"preview": "package com.example.podslidersample;\n\nimport android.graphics.drawable.Drawable;\nimport android.os.Handler;\nimport andro"
},
{
"path": "sample/src/main/java/com/example/podslidersample/PagerInteractionActivity.java",
"chars": 2458,
"preview": "package com.example.podslidersample;\n\nimport android.graphics.Color;\nimport android.support.v4.app.Fragment;\nimport andr"
},
{
"path": "sample/src/main/res/drawable/ic_android_black_24dp.xml",
"chars": 1640,
"preview": "<vector\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"200dp\"\n android:height=\"200"
},
{
"path": "sample/src/main/res/drawable/ic_android_black_24dp1.xml",
"chars": 968,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\""
},
{
"path": "sample/src/main/res/drawable/ic_build_black_24dp.xml",
"chars": 487,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\""
},
{
"path": "sample/src/main/res/drawable/ic_weekend_black_24dp.xml",
"chars": 545,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"200dp\"\n android:height="
},
{
"path": "sample/src/main/res/layout/activity_main.xml",
"chars": 1469,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmln"
},
{
"path": "sample/src/main/res/layout/activity_pager_interaction.xml",
"chars": 986,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns"
},
{
"path": "sample/src/main/res/layout/fragment_blank.xml",
"chars": 877,
"preview": "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/t"
},
{
"path": "sample/src/main/res/layout/fragment_blank_two.xml",
"chars": 874,
"preview": "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/t"
},
{
"path": "sample/src/main/res/values/colors.xml",
"chars": 257,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#3F51B5</color>\n <color name=\"color"
},
{
"path": "sample/src/main/res/values/dimens.xml",
"chars": 211,
"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": 207,
"preview": "<resources>\n <string name=\"app_name\">PodSliderSample</string>\n\n <!-- TODO: Remove or change this placeholder text "
},
{
"path": "sample/src/main/res/values/styles.xml",
"chars": 359,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"Theme.AppCompat.NoActionBar\">\n "
},
{
"path": "sample/src/main/res/values-w820dp/dimens.xml",
"chars": 358,
"preview": "<resources>\n <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n (such as s"
},
{
"path": "sample/src/test/java/com/example/podslidersample/ExampleUnitTest.java",
"chars": 320,
"preview": "package com.example.podslidersample;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * To work on unit "
},
{
"path": "settings.gradle",
"chars": 30,
"preview": "include ':sample', ':library'\n"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the bhargavms/PodSLider GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 47 files (66.9 KB), approximately 19.6k tokens, and a symbol index with 91 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.