Skip to content

Commit

Permalink
Merge pull request #119 from iamjosephmj/animation-set-interpolator
Browse files Browse the repository at this point in the history
Sort Function interpolation
  • Loading branch information
bret-fears authored Dec 15, 2020
2 parents 3a7f777 + ee96756 commit 087af65
Show file tree
Hide file tree
Showing 8 changed files with 591 additions and 5 deletions.
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,51 @@ Animator spruceAnimator = new Spruce
.start();
```

### Sort Function Interpolators

Spruce now allows the user to control the overall flow of sort function using Interpolators.

```java
Animator spruceAnimator = new Spruce
.SpruceBuilder(parentViewGroup)
.sortWith(new LinearSort(/*interObjectDelay=*/100L, /*reversed=*/false, LinearSort.Direction.TOP_TO_BOTTOM))
.addInterpolator(new LinearInterpolator())
.start();
```

Spruce gives you a wide variety of stock interpolators to choose from.

- `SpruceInterpolators.EASE`
- `SpruceInterpolators.EASE_IN`
- `SpruceInterpolators.EASE_OUT`
- `SpruceInterpolators.EASE_IN_OUT`
- `SpruceInterpolators.EASE_IN_QUAD`
- `SpruceInterpolators.EASE_IN_CUBIC`
- `SpruceInterpolators.EASE_IN_QUART`
- `SpruceInterpolators.EASE_IN_QUINT`
- `SpruceInterpolators.EASE_IN_SINE`
- `SpruceInterpolators.EASE_IN_EXPO`
- ` SpruceInterpolators.EASE_IN_CIRC`
- ` SpruceInterpolators.EASE_IN_BACK`
- ` SpruceInterpolators.EASE_OUT_QUAD`
- ` SpruceInterpolators.EASE_OUT_CUBIC`
- ` SpruceInterpolators.EASE_OUT_QUART`
- ` SpruceInterpolators.EASE_OUT_QUINT`
- ` SpruceInterpolators.EASE_OUT_SINE`
- ` SpruceInterpolators.EASE_OUT_EXPO`
- ` SpruceInterpolators.EASE_OUT_CIRC`
- ` SpruceInterpolators.EASE_OUT_BACK`
- ` SpruceInterpolators.EASE_IN_OUT_QUAD`
- ` SpruceInterpolators.EASE_IN_OUT_CUBIC`
- ` SpruceInterpolators.EASE_IN_OUT_QUART`
- ` SpruceInterpolators.EASE_IN_OUT_QUINT`
- ` SpruceInterpolators.EASE_IN_OUT_SINE`
- ` SpruceInterpolators.EASE_IN_OUT_EXPO`
- ` SpruceInterpolators.EASE_IN_OUT_CIRC`
- ` SpruceInterpolators.EASE_IN_OUT_BACK`

Checkout [interpolator documentation](https://developer.android.com/reference/android/view/animation/Interpolator) for more information.


## Stock Animators
To make everybody's lives easier, the stock animators perform basic `View` animations that a lot of apps use today. Mix and match these animators to get the core motion you are looking for.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,18 @@
package com.willowtreeapps.spurceexampleapp.fragments;

import android.animation.Animator;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
Expand Down Expand Up @@ -56,6 +63,7 @@
import com.willowtreeapps.spruce.sort.SortFunction;
import com.willowtreeapps.spurceexampleapp.R;
import com.willowtreeapps.spurceexampleapp.SpruceActivity;
import com.willowtreeapps.spurceexampleapp.helpers.InterpolatorSelector;
import com.willowtreeapps.spurceexampleapp.widgets.RadioGroupGridLayout;

import java.util.ArrayList;
Expand Down Expand Up @@ -91,6 +99,11 @@ public class ControlsFragment extends Fragment implements RadioGroupGridLayout.O
private TextView seekBarTitle;
private EditText codeSample;
private CheckBox excludeView;
private Button btnInterpolator;

private Interpolator interpolator = new LinearInterpolator();

private AlertDialog.Builder builderSingle;

private Animator[] animators;
private LinearSort.Direction direction;
Expand Down Expand Up @@ -128,12 +141,17 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, @Nullable
seekBarTitle = (TextView) rootView.findViewById(R.id.seek_bar_title);
codeSample = (EditText) rootView.findViewById(R.id.code_sample);
excludeView = (CheckBox) rootView.findViewById(R.id.view_exclusion);
btnInterpolator = (Button) rootView.findViewById(R.id.btn_interpolator);

btnInterpolator.setAllCaps(false);

animators = new Animator[]{
DefaultAnimations.shrinkAnimator(parent, /*duration=*/800),
DefaultAnimations.fadeInAnimator(parent, /*duration=*/800)
};

initInterpolatorSelection();

View.OnClickListener click = new View.OnClickListener() {
@Override
public void onClick(View v) {
Expand Down Expand Up @@ -316,6 +334,57 @@ public void onStopTrackingTouch(SeekBar seekBar) {
return rootView;
}

/**
* This method is used to set the interpolator for {@link Spruce} builder.
*/
private void initInterpolatorSelection() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
/*
* Path Interpolator is only supported only versions >=
* {@link Build.VERSION_CODES.LOLLIPOP}
*/
final InterpolatorSelector selector = new InterpolatorSelector();

builderSingle = new AlertDialog.Builder(getActivity());
builderSingle.setTitle(getResources().getString(R.string.interpolator));
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getContext(),
android.R.layout.select_dialog_singlechoice);
arrayAdapter.addAll(getResources().getStringArray(R.array.interpolator_array));
builderSingle.setNegativeButton(getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});

builderSingle.setAdapter(arrayAdapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
btnInterpolator.setText(arrayAdapter.getItem(which));
interpolator = selector.getInterpolatorMap(which);
dialog.dismiss();
}
});
initializeInterpolatorClickListener();
} else {
// Don't need to show, user can use predefined interpolator from the framework.
btnInterpolator.setVisibility(View.GONE);
}

}

/**
* This method is used to setup click listener for the interpolator selection button.
*/
private void initializeInterpolatorClickListener() {
btnInterpolator.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
builderSingle.show();
}
});
}

@Override
public void onResume() {
super.onResume();
Expand Down Expand Up @@ -418,6 +487,7 @@ private void setupSort() {

spruceAnimator = new Spruce.SpruceBuilder(parent).sortWith(sortFunction)
.animateWith(animators)
.addInterpolator(interpolator)
.excludeViews(getExclusionViews(), NORMAL_MODE)
.start();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Spruce
*
* Copyright (c) 2017 WillowTree, Inc.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/

package com.willowtreeapps.spurceexampleapp.helpers;

import android.os.Build;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;

import androidx.annotation.RequiresApi;

import com.willowtreeapps.spruce.interpolators.SpruceInterpolators;

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

/**
* This class is used to get the interpolator from {@link com.willowtreeapps.spruce.interpolators.SpruceInterpolators}
* <p>
* This class is a helper for the Interpolation selection in {@link com.willowtreeapps.spurceexampleapp.fragments.ControlsFragment}
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class InterpolatorSelector {

private final Map<Integer, Interpolator> interpolatorMap = new HashMap<>();

public InterpolatorSelector() {
initializeHashMap();
}

/**
* This hash map is used to the {@link android.app.AlertDialog} in
* {@link com.willowtreeapps.spurceexampleapp.fragments.ControlsFragment}
*/
private void initializeHashMap() {
interpolatorMap.put(0, SpruceInterpolators.EASE);
interpolatorMap.put(1, SpruceInterpolators.EASE_IN);
interpolatorMap.put(2, SpruceInterpolators.EASE_OUT);
interpolatorMap.put(3, SpruceInterpolators.EASE_IN_OUT);
interpolatorMap.put(4, SpruceInterpolators.EASE_IN_QUAD);
interpolatorMap.put(5, SpruceInterpolators.EASE_IN_CUBIC);
interpolatorMap.put(6, SpruceInterpolators.EASE_IN_QUART);
interpolatorMap.put(7, SpruceInterpolators.EASE_IN_QUINT);
interpolatorMap.put(8, SpruceInterpolators.EASE_IN_SINE);
interpolatorMap.put(9, SpruceInterpolators.EASE_IN_EXPO);
interpolatorMap.put(10, SpruceInterpolators.EASE_IN_CIRC);
interpolatorMap.put(11, SpruceInterpolators.EASE_IN_BACK);
interpolatorMap.put(12, SpruceInterpolators.EASE_OUT_QUAD);
interpolatorMap.put(13, SpruceInterpolators.EASE_OUT_CUBIC);
interpolatorMap.put(14, SpruceInterpolators.EASE_OUT_QUART);
interpolatorMap.put(15, SpruceInterpolators.EASE_OUT_QUINT);
interpolatorMap.put(16, SpruceInterpolators.EASE_OUT_SINE);
interpolatorMap.put(17, SpruceInterpolators.EASE_OUT_EXPO);
interpolatorMap.put(18, SpruceInterpolators.EASE_OUT_CIRC);
interpolatorMap.put(19, SpruceInterpolators.EASE_OUT_BACK);
interpolatorMap.put(20, SpruceInterpolators.EASE_IN_OUT_QUAD);
interpolatorMap.put(21, SpruceInterpolators.EASE_IN_OUT_CUBIC);
interpolatorMap.put(22, SpruceInterpolators.EASE_IN_OUT_QUART);
interpolatorMap.put(23, SpruceInterpolators.EASE_IN_OUT_QUINT);
interpolatorMap.put(24, SpruceInterpolators.EASE_IN_OUT_SINE);
interpolatorMap.put(25, SpruceInterpolators.EASE_IN_OUT_EXPO);
interpolatorMap.put(26, SpruceInterpolators.EASE_IN_OUT_CIRC);
interpolatorMap.put(27, SpruceInterpolators.EASE_IN_OUT_BACK);
}

/**
* This method returns the interpolator for a specific position from the {@link HashMap}
*
* @param position position from the {@link android.app.AlertDialog}
* @return {@link Interpolator} that is selected view {@link android.app.AlertDialog}
*/
public Interpolator getInterpolatorMap(int position) {
if (interpolatorMap.containsKey(position)) {
return interpolatorMap.get(position);
} else {
return new LinearInterpolator();
}
}
}
23 changes: 23 additions & 0 deletions app/src/main/res/layout/controls_fragment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,27 @@
android:layout_height="wrap_content"
android:text="@string/exclude" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginRight="0dp"
android:orientation="horizontal">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/interpolator" />

<Button
android:id="@+id/btn_interpolator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/linear_interpolator" />

</LinearLayout>


</LinearLayout>
54 changes: 54 additions & 0 deletions app/src/main/res/values/string.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!--
~ Spruce
~
~ Copyright (c) 2017 WillowTree, Inc.
~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ of this software and associated documentation files (the "Software"), to deal
~ in the Software without restriction, including without limitation the rights
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
~ copies of the Software, and to permit persons to whom the Software is
~ furnished to do so, subject to the following conditions:
~ The above copyright notice and this permission notice shall be included in
~ all copies or substantial portions of the Software.
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
~ THE SOFTWARE.
~
-->

<resources>
<string-array name="interpolator_array">
<item>ease</item>
<item>easeIn</item>
<item>easeOut</item>
<item>easeInOut</item>
<item>easeInQuad</item>
<item>easeInCubic</item>
<item>easeInQuart</item>
<item>easeInQuint</item>
<item>easeInSine</item>
<item>easeInExpo</item>
<item>easeInCirc</item>
<item>easeInBack</item>
<item>easeOutQuad</item>
<item>easeOutCubic</item>
<item>easeOutQuart</item>
<item>easeOutQuint</item>
<item>easeOutSine</item>
<item>easeOutExpo</item>
<item>easeOutCirc</item>
<item>easeOutBack</item>
<item>easeInOutQuad</item>
<item>easeInOutCubic</item>
<item>easeInOutQuart</item>
<item>easeInOutQuint</item>
<item>easeInOutSine</item>
<item>easeInOutExpo</item>
<item>easeInOutCirc</item>
<item>easeInOutBack</item>
</string-array>
</resources>
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,6 @@
<string name="snake_sort_code">new SnakeSort(%1$d, %2$s, CorneredSort.Corner.%3$s);</string>
<string name="sort_controls">Sort Controls</string>
<string name="exclude">exclude views</string>
<string name="interpolator">Interpolator</string>
<string name="linear_interpolator">linear</string>
</resources>
Loading

0 comments on commit 087af65

Please sign in to comment.