diff --git a/app/build.gradle b/app/build.gradle
index 4638cbb..afc23aa 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 23
- buildToolsVersion "23.0.2"
+ buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.hitherejoe.animate"
@@ -20,13 +20,14 @@ android {
}
dependencies {
- final SUPPORT_LIBRARY_VERSION = '23.1.1'
+ final SUPPORT_LIBRARY_VERSION = '23.4.0'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile "com.android.support:appcompat-v7:$SUPPORT_LIBRARY_VERSION"
compile "com.android.support:cardview-v7:$SUPPORT_LIBRARY_VERSION"
compile "com.android.support:design:$SUPPORT_LIBRARY_VERSION"
compile "com.android.support:recyclerview-v7:$SUPPORT_LIBRARY_VERSION"
+ compile 'com.jjoe64:graphview:4.0.1'
compile 'com.jakewharton:butterknife:7.0.1'
testCompile 'junit:junit:4.12'
diff --git a/app/src/main/java/com/hitherejoe/animate/ui/activity/InterpolatorActivity.java b/app/src/main/java/com/hitherejoe/animate/ui/activity/InterpolatorActivity.java
index f52586d..20eba7f 100644
--- a/app/src/main/java/com/hitherejoe/animate/ui/activity/InterpolatorActivity.java
+++ b/app/src/main/java/com/hitherejoe/animate/ui/activity/InterpolatorActivity.java
@@ -1,128 +1,168 @@
package com.hitherejoe.animate.ui.activity;
-import android.animation.Animator;
+import android.graphics.Color;
+import android.graphics.Path;
import android.os.Bundle;
-import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
import android.support.v7.app.ActionBar;
+import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
+import android.view.animation.PathInterpolator;
+import android.widget.AdapterView;
import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.RelativeLayout;
import android.widget.Spinner;
+import android.widget.TextView;
import com.hitherejoe.animate.R;
+import com.hitherejoe.animate.ui.widget.InterpolatorGraphView;
-import butterknife.Bind;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-
-public class InterpolatorActivity extends BaseActivity {
-
- @Bind(R.id.text_animate)
- Button mAnimateText;
-
- @Bind(R.id.layout_root)
- RelativeLayout mLayoutRoot;
-
- @Bind(R.id.spinner_interpolators)
- Spinner mInterpolatorSpinner;
-
- @Bind(R.id.fab_interpolator)
- FloatingActionButton mFloatingActionButton;
-
- private boolean mIsButtonAtTop;
+public class InterpolatorActivity extends BaseActivity implements AdapterView.OnItemSelectedListener {
+ private InterpolatorGraphView graph;
+ private View robotTest;
+ private View robotControl;
+ private boolean animateToEnd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_interpolator);
- ButterKnife.bind(this);
- mIsButtonAtTop = true;
- setupSpinnerAdapter();
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) actionBar.setDisplayHomeAsUpEnabled(true);
- }
-
- private void setupSpinnerAdapter() {
- ArrayAdapter adapter = new ArrayAdapter<>(
- this, R.layout.item_spinner, getResources().getStringArray(R.array.interpolators));
- adapter.setDropDownViewResource(R.layout.item_spinner_dropdown);
- mInterpolatorSpinner.setAdapter(adapter);
+ graph = (InterpolatorGraphView) findViewById(R.id.interpolator_activity_graph);
+ Spinner spinner = (Spinner) findViewById(R.id.interpolator_activity_spinner);
+ robotTest = findViewById(R.id.interpolator_activity_robot_test);
+ robotControl = findViewById(R.id.interpolator_activity_robot_control);
+
+ assert spinner != null;
+ assert graph != null;
+
+ spinner.setSelection(0);
+ spinner.setOnItemSelectedListener(this);
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.interpolators, android.R.layout.simple_spinner_item);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinner.setAdapter(adapter);
+ graph.applyInterpolator(new OvershootInterpolator());
+ setupToolbar();
}
- @OnClick(R.id.text_animate)
- public void animate() {
- int padding =
- mFloatingActionButton.getPaddingBottom() + mFloatingActionButton.getPaddingTop();
- int height = mLayoutRoot.getHeight() - padding;
-
+ private void setupToolbar() {
ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) height -= actionBar.getHeight();
-
- if (!mIsButtonAtTop) height = -height;
- mIsButtonAtTop = !mIsButtonAtTop;
- mFloatingActionButton.animate().setInterpolator(getSelectedInterpolator())
- .setDuration(500)
- .setStartDelay(200)
- .translationYBy(height)
- .setListener(new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- mAnimateText.setEnabled(false);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- mAnimateText.setEnabled(true);
- }
-
- @Override
- public void onAnimationCancel(Animator animation) { }
-
- @Override
- public void onAnimationRepeat(Animator animation) { }
- })
- .start();
+ if (actionBar != null) actionBar.setDisplayHomeAsUpEnabled(true);
}
- private Interpolator getSelectedInterpolator() {
- switch (mInterpolatorSpinner.getSelectedItemPosition()) {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ // 0: LinearInterpolator
+ // 1: DecelerateInterpolator
+ // 2: AccelerateInterpolator
+ // 3: AccelerateDecelerateInterpolator
+ // 4: FastOutLinearInInterpolator
+ // 5: FastOutSlowInInterpolator
+ // 6: LinearOutSlowInInterpolator
+ // 7: OvershootInterpolator
+ // 8: AnticipateInterpolator
+ // 9: AnticipateOvershootInterpolator
+ // 10: BounceInterpolator
+ // 11: PathInterpolator
+
+ ((TextView) parent.getChildAt(0)).setTextColor(Color.BLACK);
+
+ switch (position) {
+ case 0:
+ graph.applyInterpolator(new LinearInterpolator());
+ break;
case 1:
- return new FastOutLinearInInterpolator();
+ graph.applyInterpolator(
+ new InterpolatorGraphView.GraphicInterpolator(new DecelerateInterpolator(1f), "Factor: 1 (default)", Color.RED),
+ new InterpolatorGraphView.GraphicInterpolator(new DecelerateInterpolator(1.4f), "Factor: 1.4", Color.BLUE),
+ new InterpolatorGraphView.GraphicInterpolator(new DecelerateInterpolator(0.6f), "Factor: 0.6", Color.DKGRAY)
+ );
+ break;
case 2:
- return new FastOutSlowInInterpolator();
+ graph.applyInterpolator(
+ new InterpolatorGraphView.GraphicInterpolator(new AccelerateInterpolator(1f), "Factor: 1 (default)", Color.RED),
+ new InterpolatorGraphView.GraphicInterpolator(new AccelerateInterpolator(1.4f), "Factor: 1.4", Color.BLUE),
+ new InterpolatorGraphView.GraphicInterpolator(new AccelerateInterpolator(0.6f), "Factor: 0.6", Color.DKGRAY)
+ );
+ break;
case 3:
- return new LinearOutSlowInInterpolator();
+ graph.applyInterpolator(new AccelerateDecelerateInterpolator());
+ break;
case 4:
- return new AccelerateDecelerateInterpolator();
+ graph.applyInterpolator(new FastOutLinearInInterpolator());
+ break;
case 5:
- return new AccelerateInterpolator();
+ graph.applyInterpolator(new FastOutSlowInInterpolator());
+ break;
case 6:
- return new DecelerateInterpolator();
+ graph.applyInterpolator(new LinearOutSlowInInterpolator());
+ break;
case 7:
- return new AnticipateInterpolator();
+ graph.applyInterpolator(
+ new InterpolatorGraphView.GraphicInterpolator(new OvershootInterpolator(2.0f), "Tension = 2 (default)", Color.RED),
+ new InterpolatorGraphView.GraphicInterpolator(new OvershootInterpolator(2.4f), "Tension = 2.4", Color.BLUE),
+ new InterpolatorGraphView.GraphicInterpolator(new OvershootInterpolator(1.6f), "Tension = 1.6", Color.DKGRAY)
+ );
+ break;
case 8:
- return new AnticipateOvershootInterpolator();
+ graph.applyInterpolator(
+ new InterpolatorGraphView.GraphicInterpolator(new AnticipateInterpolator(2.0f), "Tension = 2 (default)", Color.RED),
+ new InterpolatorGraphView.GraphicInterpolator(new AnticipateInterpolator(2.4f), "Tension = 2.4", Color.BLUE),
+ new InterpolatorGraphView.GraphicInterpolator(new AnticipateInterpolator(1.6f), "Tension = 1.6", Color.DKGRAY)
+ );
+ break;
case 9:
- return new BounceInterpolator();
+ graph.applyInterpolator(
+ new InterpolatorGraphView.GraphicInterpolator(new AnticipateOvershootInterpolator(3.0f), "Tension = 3 (default)", Color.RED),
+ new InterpolatorGraphView.GraphicInterpolator(new AnticipateOvershootInterpolator(3.4f), "Tension = 3.4", Color.BLUE),
+ new InterpolatorGraphView.GraphicInterpolator(new AnticipateOvershootInterpolator(2.6f), "Tension = 2.6", Color.DKGRAY)
+ );
+ break;
case 10:
- return new LinearInterpolator();
+ graph.applyInterpolator(new BounceInterpolator());
+ break;
case 11:
- return new OvershootInterpolator();
- default:
- return null;
+ Path p = new Path();
+ p.moveTo(0, 0);
+ p.lineTo(0.8f, 0.2f);
+ p.lineTo(1, 1);
+ graph.applyInterpolator(
+ // http://cubic-bezier.com/#.55,.45,.86,-0.89
+ new InterpolatorGraphView.GraphicInterpolator(new PathInterpolator(0.55f, 0.45f, 0.86f, -0.89f), "Cubic (0.55, 0.45, 0.86, -0.89)", Color.RED),
+ // https://www.jasondavies.com/animated-bezier/
+ new InterpolatorGraphView.GraphicInterpolator(new PathInterpolator(0.6f, 0.2f), "Quadratic (0.6, 0.2)", Color.BLUE),
+ new InterpolatorGraphView.GraphicInterpolator(new PathInterpolator(p), "Path (0, 0; 0.8, 0.2; 1, 1)", Color.DKGRAY)
+ );
+ break;
}
}
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+
+ }
+
+ public void activateAnimation() {
+ if (!animateToEnd) {
+ robotControl.animate().translationX(graph.getWidth() - robotControl.getWidth()).setInterpolator(graph.getInterpolator()).setDuration(1000);
+ robotTest.animate().translationX(graph.getWidth() - robotControl.getWidth()).setInterpolator(new LinearInterpolator()).setDuration(1000);
+ animateToEnd = true;
+ } else {
+ robotControl.animate().translationX(0).setInterpolator(graph.getInterpolator()).setDuration(1000);
+ robotTest.animate().translationX(0).setInterpolator(new LinearInterpolator()).setDuration(1000);
+ animateToEnd = false;
+ }
+ }
+
+ public void onAnimate(View view) {
+ activateAnimation();
+ }
}
diff --git a/app/src/main/java/com/hitherejoe/animate/ui/widget/InterpolatorGraphView.java b/app/src/main/java/com/hitherejoe/animate/ui/widget/InterpolatorGraphView.java
new file mode 100644
index 0000000..bbc3d7d
--- /dev/null
+++ b/app/src/main/java/com/hitherejoe/animate/ui/widget/InterpolatorGraphView.java
@@ -0,0 +1,135 @@
+package com.hitherejoe.animate.ui.widget;
+
+import android.animation.TimeInterpolator;
+import android.content.Context;
+import android.graphics.Color;
+import android.support.annotation.NonNull;
+import android.util.AttributeSet;
+import android.view.animation.Interpolator;
+
+import com.hitherejoe.animate.R;
+import com.jjoe64.graphview.GraphView;
+import com.jjoe64.graphview.helper.StaticLabelsFormatter;
+import com.jjoe64.graphview.series.DataPoint;
+import com.jjoe64.graphview.series.LineGraphSeries;
+
+/**
+ * Created on 21/05/2016.
+ */
+public class InterpolatorGraphView extends GraphView {
+
+ private float accuracy;
+ private Interpolator interpolator;
+
+ public InterpolatorGraphView(Context context) {
+ super(context);
+ }
+
+ public InterpolatorGraphView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public InterpolatorGraphView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void init() {
+ super.init();
+
+ getViewport().setXAxisBoundsManual(true);
+ getViewport().setYAxisBoundsManual(true);
+ getViewport().setMinX(0);
+ getViewport().setMaxX(100);
+ getViewport().setMinY(-20);
+ getViewport().setMaxY(120);
+
+ getGridLabelRenderer().setHorizontalAxisTitle(getContext().getString(R.string.time));
+ getGridLabelRenderer().setVerticalAxisTitle(getContext().getString(R.string.progression));
+ StaticLabelsFormatter staticLabelsFormatter = new StaticLabelsFormatter(this);
+ staticLabelsFormatter.setHorizontalLabels(new String[] {"0%","", "", "", "", "100%"});
+ staticLabelsFormatter.setVerticalLabels(new String[] {"","0%","", "", "", "", "100%" ,""});
+ getGridLabelRenderer().setLabelFormatter(staticLabelsFormatter);
+ getGridLabelRenderer().setHorizontalAxisTitleColor(Color.BLACK);
+ getGridLabelRenderer().setVerticalAxisTitleColor(Color.BLACK);
+ getGridLabelRenderer().setHorizontalLabelsColor(Color.BLACK);
+ getGridLabelRenderer().setVerticalLabelsColor(Color.BLACK);
+
+ accuracy = 0.5f;
+ }
+
+ /**
+ * Set the accuracy of the graph
+ * @param accuracy - Lower is better, this graph will draw a point every x axis value
+ */
+ public void setAccuracy(float accuracy) {
+ this.accuracy = accuracy;
+ }
+
+ /**
+ * Draw over a graphView an interpolators graph
+ * @param interpolators - The interpolators to show
+ */
+ public void applyInterpolator(@NonNull TimeInterpolator... interpolators) {
+ removeAllSeries();
+
+ boolean firstRound = true;
+ for (TimeInterpolator interpolator : interpolators) {
+ LineGraphSeries series = new LineGraphSeries<>();
+ for (float i = 0; i <= 100; i += accuracy) {
+ series.appendData(new DataPoint(i, 100 * interpolator.getInterpolation((i / 100f))), true, (int) (101f / accuracy));
+ }
+
+ if (interpolator instanceof GraphicInterpolator) {
+ GraphicInterpolator graphicInterpolator = (GraphicInterpolator) interpolator;
+ series.setColor(graphicInterpolator.getColor());
+ series.setTitle(graphicInterpolator.getTitle());
+ if (firstRound) {
+ this.interpolator = graphicInterpolator.interpolatorInstance;
+ }
+ } else {
+ series.setColor(Color.RED);
+ if (firstRound) {
+ this.interpolator = (Interpolator) interpolator;
+ }
+ }
+
+ firstRound = false;
+ addSeries(series);
+ }
+
+ getLegendRenderer().setVisible((interpolators.length > 1));
+ getLegendRenderer().setTextColor(Color.BLACK);
+ getLegendRenderer().setBackgroundColor(Color.TRANSPARENT);
+ getLegendRenderer().setFixedPosition(0, 0);
+ }
+
+ public Interpolator getInterpolator() {
+ return interpolator;
+ }
+
+ static public class GraphicInterpolator implements TimeInterpolator {
+ private Interpolator interpolatorInstance;
+ private String title;
+ private int color;
+
+ public GraphicInterpolator(Interpolator interpolatorInstance, String title, int color) {
+ this.interpolatorInstance = interpolatorInstance;
+ this.title = title;
+ this.color = color;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public int getColor() {
+ return color;
+ }
+
+ @Override
+ public float getInterpolation(float input) {
+ return interpolatorInstance.getInterpolation(input);
+ }
+ }
+}
diff --git a/app/src/main/res/layout/activity_interpolator.xml b/app/src/main/res/layout/activity_interpolator.xml
index 6b3b40e..389a866 100644
--- a/app/src/main/res/layout/activity_interpolator.xml
+++ b/app/src/main/res/layout/activity_interpolator.xml
@@ -1,47 +1,64 @@
-
-
-
+
+
+
+
+
+
+ tools:ignore="ContentDescription"/>
+ android:layout_width="wrap_content"
+ android:layout_gravity="center"
+ android:textColor="@android:color/black"
+ android:text="@string/control_linearinterpolator"
+ android:layout_height="wrap_content"/>
-
+ tools:ignore="ContentDescription"/>
+
+
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/item_api.xml b/app/src/main/res/layout/item_api.xml
index 015a3fc..16e8fd5 100644
--- a/app/src/main/res/layout/item_api.xml
+++ b/app/src/main/res/layout/item_api.xml
@@ -2,7 +2,7 @@
Image header
Smile emotion
-
- - None
- - FastOutLinearInInterpolator
- - FastOutSlowInInterpolator
- - LinearOutSlowInInterpolator
- - AccelerateDecelerateInterpolator
- - AccelerateInterpolator
- - DecelerateInterpolator
- - AnticipateInterpolator
- - AnticipateOvershootInterpolator
- - BounceInterpolator
- - LinearInterpolator
- - OvershootInterpolator
-
-
- Fade
- Slide
@@ -119,4 +104,25 @@
- 18
+ Time
+ Progression
+ Test (Red interpolator)
+ Control (LinearInterpolator)
+ Animate!
+
+
+ - LinearInterpolator
+ - DecelerateInterpolator
+ - AccelerateInterpolator
+ - AccelerateDecelerateInterpolator
+ - FastOutLinearInInterpolator
+ - FastOutSlowInInterpolator
+ - LinearOutSlowInInterpolator
+ - OvershootInterpolator
+ - AnticipateInterpolator
+ - AnticipateOvershootInterpolator
+ - BounceInterpolator
+ - PathInterpolator
+
+
diff --git a/build.gradle b/build.gradle
index 1b7886d..f6e9073 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:1.3.0'
+ classpath 'com.android.tools.build:gradle:2.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 98841b2..dcbe5be 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Mon Nov 02 10:06:26 GMT 2015
+#Sat May 21 21:59:48 IDT 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip