children);
109 | }
110 |
111 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/willowtreeapps/spurceexampleapp/helpers/InterpolatorSelector.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spurceexampleapp.helpers;
24 |
25 | import android.os.Build;
26 | import android.view.animation.Interpolator;
27 | import android.view.animation.LinearInterpolator;
28 |
29 | import androidx.annotation.RequiresApi;
30 |
31 | import com.willowtreeapps.spruce.interpolators.SpruceInterpolators;
32 |
33 | import java.util.HashMap;
34 | import java.util.Map;
35 |
36 | /**
37 | * This class is used to get the interpolator from {@link com.willowtreeapps.spruce.interpolators.SpruceInterpolators}
38 | *
39 | * This class is a helper for the Interpolation selection in {@link com.willowtreeapps.spurceexampleapp.fragments.ControlsFragment}
40 | */
41 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
42 | public class InterpolatorSelector {
43 |
44 | private final Map interpolatorMap = new HashMap<>();
45 |
46 | public InterpolatorSelector() {
47 | initializeHashMap();
48 | }
49 |
50 | /**
51 | * This hash map is used to the {@link android.app.AlertDialog} in
52 | * {@link com.willowtreeapps.spurceexampleapp.fragments.ControlsFragment}
53 | */
54 | private void initializeHashMap() {
55 | interpolatorMap.put(0, SpruceInterpolators.EASE);
56 | interpolatorMap.put(1, SpruceInterpolators.EASE_IN);
57 | interpolatorMap.put(2, SpruceInterpolators.EASE_OUT);
58 | interpolatorMap.put(3, SpruceInterpolators.EASE_IN_OUT);
59 | interpolatorMap.put(4, SpruceInterpolators.EASE_IN_QUAD);
60 | interpolatorMap.put(5, SpruceInterpolators.EASE_IN_CUBIC);
61 | interpolatorMap.put(6, SpruceInterpolators.EASE_IN_QUART);
62 | interpolatorMap.put(7, SpruceInterpolators.EASE_IN_QUINT);
63 | interpolatorMap.put(8, SpruceInterpolators.EASE_IN_SINE);
64 | interpolatorMap.put(9, SpruceInterpolators.EASE_IN_EXPO);
65 | interpolatorMap.put(10, SpruceInterpolators.EASE_IN_CIRC);
66 | interpolatorMap.put(11, SpruceInterpolators.EASE_IN_BACK);
67 | interpolatorMap.put(12, SpruceInterpolators.EASE_OUT_QUAD);
68 | interpolatorMap.put(13, SpruceInterpolators.EASE_OUT_CUBIC);
69 | interpolatorMap.put(14, SpruceInterpolators.EASE_OUT_QUART);
70 | interpolatorMap.put(15, SpruceInterpolators.EASE_OUT_QUINT);
71 | interpolatorMap.put(16, SpruceInterpolators.EASE_OUT_SINE);
72 | interpolatorMap.put(17, SpruceInterpolators.EASE_OUT_EXPO);
73 | interpolatorMap.put(18, SpruceInterpolators.EASE_OUT_CIRC);
74 | interpolatorMap.put(19, SpruceInterpolators.EASE_OUT_BACK);
75 | interpolatorMap.put(20, SpruceInterpolators.EASE_IN_OUT_QUAD);
76 | interpolatorMap.put(21, SpruceInterpolators.EASE_IN_OUT_CUBIC);
77 | interpolatorMap.put(22, SpruceInterpolators.EASE_IN_OUT_QUART);
78 | interpolatorMap.put(23, SpruceInterpolators.EASE_IN_OUT_QUINT);
79 | interpolatorMap.put(24, SpruceInterpolators.EASE_IN_OUT_SINE);
80 | interpolatorMap.put(25, SpruceInterpolators.EASE_IN_OUT_EXPO);
81 | interpolatorMap.put(26, SpruceInterpolators.EASE_IN_OUT_CIRC);
82 | interpolatorMap.put(27, SpruceInterpolators.EASE_IN_OUT_BACK);
83 | }
84 |
85 | /**
86 | * This method returns the interpolator for a specific position from the {@link HashMap}
87 | *
88 | * @param position position from the {@link android.app.AlertDialog}
89 | * @return {@link Interpolator} that is selected view {@link android.app.AlertDialog}
90 | */
91 | public Interpolator getInterpolatorMap(int position) {
92 | if (interpolatorMap.containsKey(position)) {
93 | return interpolatorMap.get(position);
94 | } else {
95 | return new LinearInterpolator();
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/app/src/main/java/com/willowtreeapps/spurceexampleapp/model/ExampleData.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 |
24 | package com.willowtreeapps.spurceexampleapp.model;
25 |
26 | public class ExampleData {
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/willowtreeapps/spurceexampleapp/pager/VerticalViewPager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spurceexampleapp.pager;
24 |
25 | import android.content.Context;
26 | import android.util.AttributeSet;
27 | import android.view.MotionEvent;
28 | import android.view.View;
29 |
30 | import androidx.viewpager.widget.ViewPager;
31 |
32 | public class VerticalViewPager extends ViewPager {
33 |
34 | public VerticalViewPager(Context context) {
35 | super(context);
36 | init();
37 | }
38 |
39 | public VerticalViewPager(Context context, AttributeSet attrs) {
40 | super(context, attrs);
41 | init();
42 | }
43 |
44 | private void init() {
45 | setPageTransformer(true, new VerticalPageTransformer());
46 | setOverScrollMode(OVER_SCROLL_NEVER);
47 | }
48 |
49 | @Override
50 | public boolean onInterceptTouchEvent(MotionEvent ev){
51 | boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
52 | swapXY(ev);
53 | return intercepted;
54 | }
55 |
56 | @Override
57 | public boolean onTouchEvent(MotionEvent ev) {
58 | return super.onTouchEvent(swapXY(ev));
59 | }
60 |
61 | private MotionEvent swapXY(MotionEvent ev) {
62 | float width = getWidth();
63 | float height = getHeight();
64 |
65 | float newX = (ev.getY() / height) * width;
66 | float newY = (ev.getX() / width) * height;
67 |
68 | ev.setLocation(newX, newY);
69 |
70 | return ev;
71 | }
72 |
73 | private class VerticalPageTransformer implements ViewPager.PageTransformer {
74 |
75 | @Override
76 | public void transformPage(View view, float position) {
77 |
78 | if (position < -1) {
79 | view.setAlpha(0);
80 |
81 | } else if (position <= 1) {
82 | view.setAlpha(1);
83 |
84 | view.setTranslationX(view.getWidth() * -position);
85 |
86 | float yPosition = position * view.getHeight();
87 | view.setTranslationY(yPosition);
88 |
89 | } else {
90 | view.setAlpha(0);
91 | }
92 | }
93 | }
94 |
95 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/willowtreeapps/spurceexampleapp/widgets/CardLayout.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spurceexampleapp.widgets;
24 |
25 | import android.content.Context;
26 | import android.util.AttributeSet;
27 | import android.view.LayoutInflater;
28 | import android.widget.LinearLayout;
29 |
30 | import com.willowtreeapps.spurceexampleapp.R;
31 |
32 | import androidx.annotation.Nullable;
33 |
34 | public class CardLayout extends LinearLayout {
35 |
36 | public CardLayout(Context context) {
37 | super(context);
38 | init();
39 | }
40 |
41 | public CardLayout(Context context, @Nullable AttributeSet attrs) {
42 | super(context, attrs);
43 | init();
44 | }
45 |
46 | public CardLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
47 | super(context, attrs, defStyleAttr);
48 | init();
49 | }
50 |
51 | private void init() {
52 | LayoutInflater inflater = LayoutInflater.from(getContext());
53 | inflater.inflate(R.layout.view_card, this, true);
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_arrow_drop_down_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/drawable-hdpi/ic_arrow_drop_down_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/spruce_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/drawable-hdpi/spruce_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_arrow_drop_down_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/drawable-mdpi/ic_arrow_drop_down_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/spruce_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/drawable-mdpi/spruce_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_arrow_drop_down_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/drawable-xhdpi/ic_arrow_drop_down_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/spruce_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/drawable-xhdpi/spruce_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_arrow_drop_down_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/drawable-xxhdpi/ic_arrow_drop_down_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/spruce_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/drawable-xxhdpi/spruce_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_arrow_drop_down_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/drawable-xxxhdpi/ic_arrow_drop_down_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/spruce_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/drawable-xxxhdpi/spruce_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/code_sample_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_keyboard_arrow_up_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
30 |
31 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/continuous_radio_group.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
27 |
28 |
32 |
33 |
39 |
40 |
45 |
46 |
50 |
51 |
56 |
57 |
63 |
64 |
69 |
70 |
71 |
72 |
73 |
74 |
80 |
81 |
86 |
87 |
91 |
92 |
97 |
98 |
104 |
105 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/cornered_radio_group.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
27 |
28 |
33 |
34 |
40 |
41 |
46 |
47 |
52 |
53 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/directional_radio_group.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
27 |
28 |
33 |
34 |
40 |
41 |
46 |
47 |
52 |
53 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_pager.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
29 |
30 |
36 |
37 |
43 |
44 |
45 |
46 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_view_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
29 |
30 |
36 |
37 |
38 |
39 |
44 |
45 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/positional_radio_group.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
27 |
28 |
34 |
35 |
41 |
42 |
47 |
48 |
53 |
54 |
59 |
60 |
65 |
66 |
71 |
72 |
77 |
78 |
83 |
84 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/recycler_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
29 |
30 |
36 |
37 |
38 |
39 |
44 |
45 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/spinner_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_card.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
30 |
31 |
40 |
41 |
48 |
49 |
50 |
51 |
58 |
59 |
63 |
64 |
71 |
72 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_placeholder.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
29 |
30 |
40 |
41 |
52 |
53 |
65 |
66 |
78 |
79 |
85 |
86 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
22 |
23 |
24 |
27 | 64dp
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
25 | #3BB894
26 | #2e7d32
27 | #8BC34A
28 | #4bc495
29 | #FFFFFF
30 | #000000
31 | #DDDDDD
32 | #939393
33 | #F8F8F9
34 | #D9E1E2
35 | #DBE9F9
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
22 |
23 |
24 |
25 | 16dp
26 | 16dp
27 | 96dp
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/values/sort_functions_array.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
25 |
26 | - @string/default_sort
27 | - @string/cornered_sort
28 | - @string/continuous_sort
29 | - @string/continuous_weighted_sort
30 | - @string/inline_sort
31 | - @string/linear_sort
32 | - @string/radial_sort
33 | - @string/random_sort
34 | - @string/snake_sort
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/values/string.xml:
--------------------------------------------------------------------------------
1 |
22 |
23 |
24 |
25 | - ease
26 | - easeIn
27 | - easeOut
28 | - easeInOut
29 | - easeInQuad
30 | - easeInCubic
31 | - easeInQuart
32 | - easeInQuint
33 | - easeInSine
34 | - easeInExpo
35 | - easeInCirc
36 | - easeInBack
37 | - easeOutQuad
38 | - easeOutCubic
39 | - easeOutQuart
40 | - easeOutQuint
41 | - easeOutSine
42 | - easeOutExpo
43 | - easeOutCirc
44 | - easeOutBack
45 | - easeInOutQuad
46 | - easeInOutCubic
47 | - easeInOutQuart
48 | - easeInOutQuint
49 | - easeInOutSine
50 | - easeInOutExpo
51 | - easeInOutCirc
52 | - easeInOutBack
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
22 |
23 |
24 | Spruce
25 | Recycler Example
26 | List View Example
27 |
28 |
29 | Sort Example
30 | Recycler View Example
31 | List View Example
32 |
33 | Default Sort
34 | Cornered Sort
35 | Continuous Sort
36 | Continuous Weighted Sort
37 | Inline Sort
38 | Linear Sort
39 | Radial Sort
40 | Random Sort
41 | Snake Sort
42 |
43 | Bottom to Top
44 | Top to Bottom
45 | Left to Right
46 | Right to Left
47 |
48 | Top Left
49 | Top Middle
50 | Top Right
51 | Right
52 | Middle
53 | Left
54 | Bottom Left
55 | Bottom Middle
56 | Bottom Right
57 |
58 | Light
59 | Medium
60 | Heavy
61 |
62 | Reversed
63 |
64 | Vertical
65 | Horizontal
66 | 0s
67 | 0.1s
68 | 2s
69 | Duration
70 | Delay
71 | Sort function:
72 | Sort Function selection
73 | Select
74 | Cancel
75 |
76 |
77 | Code Sample
78 | new DefaultSort(%1$d);
79 | new CorneredSort(%1$d, %2$s, CorneredSort.Corner.%3$s);
80 | new ContinuousSort(%1$d, %2$s, RadialSort.Position.%3$s);
81 | new ContinuousWeightedSort(%1$d, %2$s, RadialSort.Position.%3$s, %4$s, %5$s);
82 | new InlineSort(%1$d, %2$s, CorneredSort.Corner.%3$s);
83 | new LinearSort(%1$d, %2$s, LinearSort.Direction.%3$s);
84 | new RadialSort(%1$d, %2$s, RadialSort.Position.%3$s);
85 | new RandomSort(%1$d);
86 | new SnakeSort(%1$d, %2$s, CorneredSort.Corner.%3$s);
87 | Sort Controls
88 | exclude views
89 | Interpolator
90 | linear
91 |
92 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
22 |
23 |
24 |
25 |
26 |
34 |
35 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.3.72'
5 |
6 | repositories {
7 | jcenter()
8 | google()
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.5.4'
12 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
13 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5'
14 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
15 |
16 | // NOTE: Do not place your application dependencies here; they belong
17 | // in the individual module build.gradle files
18 | }
19 | }
20 |
21 | allprojects {
22 | repositories {
23 | jcenter()
24 | google()
25 | }
26 | }
27 |
28 | task clean(type: Delete) {
29 | delete rootProject.buildDir
30 | }
31 |
32 | // Define versions in a single place
33 | ext {
34 | // Sdk and Tools
35 | min_sdk_version = 16
36 | target_sdk_version = 30
37 | compile_sdk_version = 30
38 |
39 | //Library data
40 | version_name = '1.1.0'
41 | version_code = 1
42 | group_name = "com.willowtreeapps.spruce"
43 | lib_name = 'spruce-android'
44 | lib_desc = 'lightweight animation library'
45 |
46 | //dev details
47 | dev_id = 'willowtreeapps'
48 | dev_name = 'WillowTree Inc'
49 | dev_email = 'developer@willowtreeapps.com'
50 |
51 | //license
52 | license_name = 'MIT License'
53 | license_url = 'https://opensource.org/licenses/MIT'
54 |
55 | //General
56 | androidx_appcompact = '1.2.0'
57 | kotlin_collections_ktx = '1.1.0'
58 | recycler_view = '1.1.0'
59 | multidex = '2.0.1'
60 | timber = '4.7.1'
61 | kotlin_project_version = '1.3.2'
62 |
63 | //Local Test
64 | local_junit_version = '4.12'
65 | local_mokito_version = '2.19.0'
66 | local_robo_electric_version = '4.1'
67 |
68 | //UI Test
69 | ui_test_runner_version = '1.3.0'
70 | ui_junit_version = '1.1.2'
71 | ui_espresso_core_version = '3.1.0'
72 | ui_espresso_intent_version = '3.1.0'
73 |
74 | }
--------------------------------------------------------------------------------
/code-of-conduct.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of experience,
9 | nationality, personal appearance, race, religion, or sexual identity and
10 | orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at open.source.conduct@willowtreeapps.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at [http://contributor-covenant.org/version/1/4][version]
72 |
73 | [homepage]: http://contributor-covenant.org
74 | [version]: http://contributor-covenant.org/version/1/4/
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | android.enableJetifier=true
13 | android.useAndroidX=true
14 | org.gradle.jvmargs=-Xmx1536m
15 |
16 | # When configured, Gradle will run in incubating parallel mode.
17 | # This option should only be used with decoupled projects. More details, visit
18 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
19 | # org.gradle.parallel=true
20 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Feb 04 15:27:17 EST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/imgs/bottom-right-corner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/imgs/bottom-right-corner.gif
--------------------------------------------------------------------------------
/imgs/header_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/imgs/header_image.png
--------------------------------------------------------------------------------
/imgs/recycler-example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/imgs/recycler-example.gif
--------------------------------------------------------------------------------
/imgs/top-left-corner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/imgs/top-left-corner.gif
--------------------------------------------------------------------------------
/imgs/willowtree_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/willowtreeapps/spruce-android/06924982d71c5fa73582678e4331a3f88e0b92dc/imgs/willowtree_logo.png
--------------------------------------------------------------------------------
/lib/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/lib/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/bretfears/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/lib/src/androidTest/java/com/willowtreeapps/spruce/AnimationActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce;
24 |
25 | import android.app.Activity;
26 | import android.os.Bundle;
27 |
28 | import com.willowtreeapps.spruce.R;
29 |
30 | public class AnimationActivity extends Activity {
31 | @Override
32 | public void onCreate(Bundle bundle) {
33 | super.onCreate(bundle);
34 | setContentView(R.layout.anim_layout);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/lib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/SpruceAnimator.java:
--------------------------------------------------------------------------------
1 | package com.willowtreeapps.spruce;
2 |
3 | import android.animation.AnimatorSet;
4 |
5 | import com.willowtreeapps.spruce.dynamics.DynamicAnimatorSet;
6 |
7 | /**
8 | * This is a wrapper class for holding animation set and {@link DynamicAnimatorSet}
9 | */
10 | public class SpruceAnimator {
11 | private AnimatorSet animatorSet = new AnimatorSet();
12 | private DynamicAnimatorSet dynamicAnimatorSet = new DynamicAnimatorSet();
13 |
14 | public AnimatorSet getAnimatorSet() {
15 | return animatorSet;
16 | }
17 |
18 | public void setAnimatorSet(AnimatorSet animatorSet) {
19 | this.animatorSet = animatorSet;
20 | }
21 |
22 | public DynamicAnimatorSet getDynamicAnimatorSet() {
23 | return dynamicAnimatorSet;
24 | }
25 |
26 | public void setDynamicAnimatorSet(DynamicAnimatorSet dynamicAnimatorSet) {
27 | this.dynamicAnimatorSet = dynamicAnimatorSet;
28 | }
29 |
30 | /**
31 | * cancels all the animation that are presently performed.
32 | */
33 | public void cancel() {
34 | animatorSet.cancel();
35 | dynamicAnimatorSet.cancel();
36 | }
37 |
38 | /**
39 | * starts all the animations that are queued.
40 | */
41 | public void start() {
42 | animatorSet.start();
43 | dynamicAnimatorSet.start();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/animation/DefaultAnimations.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.animation;
24 |
25 | import android.animation.Animator;
26 | import android.animation.ObjectAnimator;
27 | import android.animation.PropertyValuesHolder;
28 | import android.view.View;
29 |
30 | import com.willowtreeapps.spruce.dynamics.SpruceDynamics;
31 | import com.willowtreeapps.spruce.dynamics.SpruceSpringAnimation;
32 | import com.willowtreeapps.spruce.dynamics.SpringForce;
33 |
34 | /**
35 | * Convenience methods for retrieving default view animators
36 | */
37 | public class DefaultAnimations {
38 |
39 | private static final float GROW_SCALE = 1.5F;
40 | private static final float SHRINK_SCALE = 0.1F;
41 | private static final float ORIGINAL_SCALE = 1.0F;
42 | private static final float FADE_AWAY_TO = 0.0F;
43 | private static final float FADE_IN_TO = 1.0F;
44 | private static final float FADE_FROM = 0.0F;
45 | private static final float START_ROTATION = 0F;
46 | private static final float END_ROTATION = 360F;
47 |
48 | public static Animator growAnimator(View view, long duration) {
49 | return ObjectAnimator.ofPropertyValuesHolder(view,
50 | PropertyValuesHolder.ofFloat(View.SCALE_X, GROW_SCALE, ORIGINAL_SCALE),
51 | PropertyValuesHolder.ofFloat(View.SCALE_Y, GROW_SCALE, ORIGINAL_SCALE))
52 | .setDuration(duration);
53 | }
54 |
55 | public static Animator shrinkAnimator(View view, long duration) {
56 | return ObjectAnimator.ofPropertyValuesHolder(view,
57 | PropertyValuesHolder.ofFloat(View.SCALE_X, SHRINK_SCALE, ORIGINAL_SCALE),
58 | PropertyValuesHolder.ofFloat(View.SCALE_Y, SHRINK_SCALE, ORIGINAL_SCALE))
59 | .setDuration(duration);
60 | }
61 |
62 | public static Animator fadeAwayAnimator(View view, long duration) {
63 | return ObjectAnimator.ofFloat(view, View.ALPHA, FADE_AWAY_TO)
64 | .setDuration(duration);
65 | }
66 |
67 | public static Animator fadeInAnimator(View view, long duration) {
68 | return ObjectAnimator.ofFloat(view, View.ALPHA, FADE_FROM, FADE_IN_TO)
69 | .setDuration(duration);
70 | }
71 |
72 | public static Animator spinAnimator(View view, long duration) {
73 | return ObjectAnimator.ofFloat(view, View.ROTATION, START_ROTATION, END_ROTATION)
74 | .setDuration(duration);
75 | }
76 |
77 | public static SpruceSpringAnimation dynamicTranslationUpwards(View view) {
78 | SpruceSpringAnimation tranUp = new SpruceSpringAnimation(view, SpruceDynamics.TRANSLATION_Y)
79 | .setStartValue(200f);
80 | tranUp.setSpring(new SpringForce());
81 | tranUp.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY);
82 | tranUp.getSpring().setStiffness(SpringForce.STIFFNESS_LOW);
83 | tranUp.getSpring().setFinalPosition(FADE_FROM);
84 | return tranUp;
85 | }
86 |
87 | public static SpruceSpringAnimation dynamicFadeIn(View view) {
88 | SpruceSpringAnimation tranUp = new SpruceSpringAnimation(view, SpruceDynamics.ALPHA)
89 | .setStartValue(FADE_FROM);
90 | tranUp.setSpring(new SpringForce());
91 | tranUp.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY);
92 | tranUp.getSpring().setStiffness(SpringForce.STIFFNESS_MEDIUM);
93 | tranUp.getSpring().setFinalPosition(FADE_IN_TO);
94 | return tranUp;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/dynamics/DynamicAnimation.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.dynamics
24 |
25 | /**
26 | * Creates [SpruceFlingAnimation] for a property that can be accessed via the provided setter and getter.
27 | * For example, the following sample code creates a [SpruceFlingAnimation] for the alpha property of a
28 | * [View] object named `view`:
29 | * `flingAnimationOf(view::setAlpha, view::getAlpha)`
30 | *
31 | * @param setter The function that mutates the property being animated
32 | * @param getter The function that returns the value of the property
33 | * @return [SpruceFlingAnimation]
34 | */
35 | fun flingAnimationOf(setter: (Float) -> Unit, getter: () -> Float): SpruceFlingAnimation {
36 | return SpruceFlingAnimation(createFloatValueHolder(setter, getter))
37 | }
38 |
39 | /**
40 | * Creates [SpruceSpringAnimation] for a property that can be accessed via the provided setter and getter.
41 | * If finalPosition is not [Float.NaN] then create [SpruceSpringAnimation] with
42 | * [SpringForce.mFinalPosition].
43 | *
44 | * @param setter The function that mutates the property being animated
45 | * @param getter The function that returns the value of the property
46 | * @param finalPosition [SpringForce.mFinalPosition] Final position of spring.
47 | * @return [SpruceSpringAnimation]
48 | */
49 | fun springAnimationOf(
50 | setter: (Float) -> Unit,
51 | getter: () -> Float,
52 | finalPosition: Float = Float.NaN
53 | ): SpruceSpringAnimation {
54 | val valueHolder = createFloatValueHolder(setter, getter)
55 | return if (finalPosition.isNaN()) {
56 | SpruceSpringAnimation(valueHolder)
57 | } else {
58 | SpruceSpringAnimation(valueHolder, finalPosition)
59 | }
60 | }
61 |
62 | /**
63 | * Updates or applies spring force properties like [SpringForce.mDampingRatio],
64 | * [SpringForce.mFinalPosition] and stiffness on SpringAnimation.
65 | *
66 | * If [SpruceSpringAnimation.mSpring] is null in case [SpruceSpringAnimation] is created without final position
67 | * it will be created and attached to [SpruceSpringAnimation]
68 | *
69 | * @param func lambda with receiver on [SpringForce]
70 | * @return [SpruceSpringAnimation]
71 | */
72 | inline fun SpruceSpringAnimation.withSpringForceProperties(
73 | func: SpringForce.() -> Unit
74 | ): SpruceSpringAnimation {
75 | if (spring == null) {
76 | spring = SpringForce()
77 | }
78 | spring.func()
79 | return this
80 | }
81 |
82 | private fun createFloatValueHolder(setter: (Float) -> Unit, getter: () -> Float): FloatValueHolder {
83 | return object : FloatValueHolder() {
84 | override fun getValue(): Float {
85 | return getter.invoke()
86 | }
87 |
88 | override fun setValue(value: Float) {
89 | setter.invoke(value)
90 | }
91 | }
92 | }
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/dynamics/DynamicAnimatorSet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.dynamics;
24 |
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | /**
29 | * This class is eqivalent to {@link android.view.animation.AnimationSet} for dynamic animations.
30 | */
31 | public class DynamicAnimatorSet {
32 |
33 | private List> anim = new ArrayList<>();
34 |
35 | /**
36 | * Sets up this AnimatorSet to play all of the supplied animations at the same time.
37 | *
38 | * @param items The animations that will be started simultaneously.
39 | */
40 | public void playTogether(List> items) {
41 | anim = items;
42 | }
43 |
44 | /**
45 | * This method is used to cancel the animation.
46 | */
47 | public void cancel() {
48 | for (SpruceDynamics> anim : anim) {
49 | anim.cancel();
50 | }
51 | }
52 |
53 |
54 | /**
55 | * This method is used to start all queued dynamic animations.
56 | */
57 | public void start() {
58 | for (SpruceDynamics> anim : anim) {
59 | anim.start();
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/dynamics/FloatPropertyCompat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.dynamics;
24 |
25 | import android.util.FloatProperty;
26 |
27 | import androidx.annotation.RequiresApi;
28 |
29 | /**
30 | * FloatPropertyCompat is an abstraction that can be used to represent a mutable float value that
31 | * is held in a host object. To access this float value, {@link #setValue(Object, float)} and getter
32 | * {@link #getValue(Object)} need to be implemented. Both the setter and the getter take the
33 | * primitive float
type and avoids autoboxing and other overhead associated with the
34 | * Float
class.
35 | *
36 | *
For API 24 and later, {@link FloatProperty} instances can be converted to
37 | * {@link FloatPropertyCompat} through
38 | * {@link FloatPropertyCompat#createFloatPropertyCompat(FloatProperty)}.
39 | *
40 | * @param the class on which the Property is declared
41 | */
42 | public abstract class FloatPropertyCompat {
43 | final String mPropertyName;
44 |
45 | /**
46 | * A constructor that takes an identifying name.
47 | */
48 | public FloatPropertyCompat(String name) {
49 | mPropertyName = name;
50 | }
51 |
52 | /**
53 | * Create a {@link FloatPropertyCompat} wrapper for a {@link FloatProperty} object. The new
54 | * {@link FloatPropertyCompat} instance will access and modify the property value of
55 | * {@link FloatProperty} through the {@link FloatProperty} instance's setter and getter.
56 | *
57 | * @param property FloatProperty instance to be wrapped
58 | * @param the class on which the Property is declared
59 | * @return a new {@link FloatPropertyCompat} wrapper for the given {@link FloatProperty} object
60 | */
61 | @RequiresApi(24)
62 | public static FloatPropertyCompat createFloatPropertyCompat(
63 | final FloatProperty property) {
64 | return new FloatPropertyCompat(property.getName()) {
65 | @Override
66 | public float getValue(T object) {
67 | return property.get(object);
68 | }
69 |
70 | @Override
71 | public void setValue(T object, float value) {
72 | property.setValue(object, value);
73 | }
74 | };
75 | }
76 |
77 | /**
78 | * Returns the current value that this property represents on the given object
.
79 | *
80 | * @param object object which this property represents
81 | * @return the current property value of the given object
82 | */
83 | public abstract float getValue(T object);
84 |
85 | /**
86 | * Sets the value on object
which this property represents.
87 | *
88 | * @param object object which this property represents
89 | * @param value new value of the property
90 | */
91 | public abstract void setValue(T object, float value);
92 | }
93 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/dynamics/FloatValueHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.dynamics;
24 |
25 | /**
26 | * FloatValueHolder holds a float value. FloatValueHolder provides a setter and a getter (
27 | * i.e. {@link #setValue(float)} and {@link #getValue()}) to access this float value. Animations can
28 | * be performed on a FloatValueHolder instance. During each frame of the animation, the
29 | * FloatValueHolder will have its value updated via {@link #setValue(float)}. The caller can
30 | * obtain the up-to-date animation value via {@link FloatValueHolder#getValue()}.
31 | *
32 | *
Here is an example for creating a {@link SpruceFlingAnimation} with a FloatValueHolder:
33 | *
34 | * // Create a fling animation with an initial velocity of 5000 (pixel/s) and an initial position
35 | * // of 20f.
36 | * FloatValueHolder floatValueHolder = new FloatValueHolder(20f);
37 | * FlingAnimation anim = new FlingAnimation(floatValueHolder).setStartVelocity(5000);
38 | * anim.start();
39 | *
40 | *
41 | * @see SpruceSpringAnimation#SpruceSpringAnimation(FloatValueHolder)
42 | * @see SpruceFlingAnimation#SpruceFlingAnimation(FloatValueHolder)
43 | */
44 |
45 | public class FloatValueHolder {
46 | private float mValue = 0.0f;
47 |
48 | /**
49 | * Constructs a holder for a float value that is initialized to 0.
50 | */
51 | public FloatValueHolder() {
52 | }
53 |
54 | /**
55 | * Constructs a holder for a float value that is initialized to the input value.
56 | *
57 | * @param value the value to initialize the value held in the FloatValueHolder
58 | */
59 | public FloatValueHolder(float value) {
60 | setValue(value);
61 | }
62 |
63 | /**
64 | * Sets the value held in the FloatValueHolder instance.
65 | *
66 | * @param value float value held in the FloatValueHolder instance
67 | */
68 | public void setValue(float value) {
69 | mValue = value;
70 | }
71 |
72 | /**
73 | * Returns the float value held in the FloatValueHolder instance.
74 | *
75 | * @return float value held in the FloatValueHolder instance
76 | */
77 | public float getValue() {
78 | return mValue;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/dynamics/Force.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.dynamics;
24 |
25 | /**
26 | * Hide this for now, in case we want to change the API.
27 | */
28 | interface Force {
29 | // Acceleration based on position.
30 | float getAcceleration(float position, float velocity);
31 |
32 | boolean isAtEquilibrium(float value, float velocity);
33 | }
34 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/exclusion/ExclusionHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.exclusion;
24 |
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 |
28 | import java.util.ArrayList;
29 | import java.util.HashMap;
30 | import java.util.List;
31 |
32 | /**
33 | * This class takes care of the exclusion functionality
34 | */
35 | public class ExclusionHelper {
36 |
37 | private final HashMap exclusionMap = new HashMap<>();
38 | private int mode;
39 | public static final int R_L_MODE = 0;
40 | public static final int NORMAL_MODE = 1;
41 |
42 | /**
43 | * This method is used to initialize the exclusion module.
44 | *
45 | * @param exclusionList list of items to be excluded.
46 | * @param mode mode in which the exclusion works.
47 | */
48 | public void initialize(List exclusionList, int mode) {
49 | /*
50 | * making hash-map from the given list.
51 | * This is to cut down the complexity in the future.
52 | */
53 | this.mode = mode;
54 | for (Integer id : exclusionList) {
55 | exclusionMap.put(id, true);
56 | }
57 | }
58 |
59 | /**
60 | * isToBeIncluded function works in 2 modes,
61 | * 1. ID mode : exclude if the ID is present.
62 | * 2. Index mode: exclude a specific index.
63 | *
64 | * @param view the view to be checked for exclusion.
65 | * @param index index of the view/
66 | * @return true of the view is to be included else excluded.
67 | */
68 | public boolean isToBeIncluded(View view, int index) {
69 | if (mode == NORMAL_MODE) {
70 | return view != null && !exclusionMap.containsKey(view.getId());
71 | } else if (mode == R_L_MODE) {
72 | return view != null && !exclusionMap.containsKey(index);
73 | }
74 | return false;
75 | }
76 |
77 | /**
78 | * filterViews function will filter out the {@link HashMap} exclusionMap from the parent view group.
79 | *
80 | * @param viewGroup parent view group
81 | * @return returns filtered list of type view
82 | */
83 | public List filterViews(ViewGroup viewGroup) {
84 | List children = new ArrayList<>();
85 |
86 | /*
87 | * The reason why we use hash map for the comparison is because
88 | * HashMap has complexity of O(1) for insertion and lookup.
89 | * this will keep the overall complexity as O(n).
90 | */
91 | for (int index = 0; index < viewGroup.getChildCount(); index++) {
92 | View view = viewGroup.getChildAt(index);
93 | if (isToBeIncluded(view, index))
94 | children.add(view);
95 | }
96 | return children;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/sort/ContinuousSort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.graphics.PointF;
26 | import android.view.View;
27 | import android.view.ViewGroup;
28 |
29 | import java.util.ArrayList;
30 | import java.util.Collections;
31 | import java.util.Comparator;
32 | import java.util.List;
33 |
34 | public class ContinuousSort extends RadialSort {
35 |
36 | private final long duration;
37 | private final boolean reversed;
38 |
39 | /**
40 | * Establishes the delay between object animations and their starting position based on distance,
41 | * delay, and a value from the Position enum
42 | *
43 | * @param interObjectDelay delay between object animations
44 | * @param reversed flag to indicate if the animation should be reversed
45 | * @param position enum value of the position the animation should start from
46 | */
47 | public ContinuousSort(long interObjectDelay, boolean reversed, Position position) {
48 | super(interObjectDelay, reversed, position);
49 | this.duration = interObjectDelay;
50 | this.reversed = reversed;
51 | }
52 |
53 | @Override
54 | public List getViewListWithTimeOffsets(ViewGroup parent, List children) {
55 | final PointF comparisonPoint = getDistancePoint(parent, children);
56 |
57 | double maxDistance = 0;
58 | for (View v : children) {
59 | double distance = getDistanceBetweenPoints(Utils.viewToPoint(v), comparisonPoint);
60 | if (distance > maxDistance) {
61 | maxDistance = distance;
62 | }
63 | }
64 |
65 | List timedViews = new ArrayList<>();
66 | for (View view : children) {
67 | double normalizedDistance;
68 | double viewDistance = getDistanceBetweenPoints(Utils.viewToPoint(view), comparisonPoint);
69 | if (reversed) {
70 | normalizedDistance = (maxDistance - viewDistance) / maxDistance;
71 | } else {
72 | normalizedDistance = viewDistance / maxDistance;
73 | }
74 |
75 | long offset = Math.round(duration * normalizedDistance);
76 | timedViews.add(new SpruceTimedView(view, offset));
77 | }
78 |
79 | return timedViews;
80 | }
81 |
82 | @Override
83 | public void sortChildren(ViewGroup parent, List children) {
84 | final PointF comparisonPoint = getDistancePoint(parent, children);
85 | Collections.sort(children, new Comparator() {
86 | @Override
87 | public int compare(View left, View right) {
88 | double leftDistance = getDistanceBetweenPoints(Utils.viewToPoint(left), comparisonPoint);
89 | double rightDistance = getDistanceBetweenPoints(Utils.viewToPoint(right), comparisonPoint);
90 | return Double.compare(leftDistance, rightDistance);
91 | }
92 | });
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/sort/CorneredSort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.graphics.PointF;
26 | import android.view.View;
27 | import android.view.ViewGroup;
28 |
29 | import java.util.ArrayList;
30 | import java.util.Collections;
31 | import java.util.Comparator;
32 | import java.util.List;
33 |
34 | public class CorneredSort extends DistancedSort {
35 |
36 | public enum Corner {
37 | TOP_LEFT,
38 | TOP_RIGHT,
39 | BOTTOM_LEFT,
40 | BOTTOM_RIGHT
41 | }
42 |
43 | private final long interObjectDelay;
44 | private final Corner corner;
45 | private final boolean reversed;
46 |
47 | /**
48 | * Animates views in a corner like fashion. The views near the starting corner will animate first.
49 | *
50 | * @param interObjectDelay long delay between objects
51 | * @param reversed boolean
52 | * @param corner Corner enum value {@link Corner corner}
53 | */
54 | public CorneredSort(long interObjectDelay, boolean reversed, Corner corner) {
55 | super(interObjectDelay, reversed);
56 | if (corner == null) {
57 | throw new NullPointerException("Corner can't be null and must be a valid type");
58 | }
59 | this.interObjectDelay = interObjectDelay;
60 | this.corner = corner;
61 | this.reversed = reversed;
62 | }
63 |
64 | @Override
65 | public List getViewListWithTimeOffsets(ViewGroup parent, List children) {
66 | final PointF comparisonPoint = getDistancePoint(parent, children);
67 | List timedViews = new ArrayList<>();
68 | long currentTimeOffset = 0;
69 |
70 | double lastDistance = 0;
71 | for (View view : children) {
72 | double viewDistance = getDistanceBetweenPoints(Utils.viewToPoint(view), comparisonPoint);
73 | if (Math.floor(lastDistance) != Math.floor(viewDistance)) {
74 | lastDistance = viewDistance;
75 | currentTimeOffset += interObjectDelay;
76 | }
77 | timedViews.add(new SpruceTimedView(view, currentTimeOffset));
78 | }
79 |
80 | return timedViews;
81 | }
82 |
83 | @Override
84 | public void sortChildren(ViewGroup parent, List children) {
85 | final PointF comparisonPoint = getDistancePoint(parent, children);
86 | Collections.sort(children, new Comparator() {
87 | @Override
88 | public int compare(View left, View right) {
89 | double leftDistance = Math.abs(comparisonPoint.x - left.getX()) + Math.abs(comparisonPoint.y - left.getY());
90 | double rightDistance = Math.abs(comparisonPoint.x - right.getX()) + Math.abs(comparisonPoint.y - right.getY());
91 | if (reversed) {
92 | return Double.compare(rightDistance, leftDistance);
93 | }
94 | return Double.compare(leftDistance, rightDistance);
95 | }
96 | });
97 | }
98 |
99 | @Override
100 | public PointF getDistancePoint(ViewGroup parent, List children) {
101 | PointF distancePoint;
102 |
103 | switch (corner) {
104 | case TOP_LEFT:
105 | distancePoint = new PointF(0, 0);
106 | break;
107 | case TOP_RIGHT:
108 | distancePoint = new PointF(parent.getWidth(), 0);
109 | break;
110 | case BOTTOM_LEFT:
111 | distancePoint = new PointF(0, parent.getHeight());
112 | break;
113 | case BOTTOM_RIGHT:
114 | distancePoint = new PointF(parent.getWidth(), parent.getHeight());
115 | break;
116 | default:
117 | throw new AssertionError("Must be a valid Corner argument type");
118 | }
119 |
120 | return distancePoint;
121 | }
122 |
123 | }
124 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/sort/DefaultSort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 |
28 | import java.util.ArrayList;
29 | import java.util.List;
30 |
31 | public class DefaultSort extends SortFunction {
32 |
33 | private final long interObjectDelay;
34 |
35 | /**
36 | * Default sort; handles views with a provided offset delay
37 | * @param interObjectDelay (long) delay between object animations
38 | */
39 | public DefaultSort(long interObjectDelay) {
40 | this.interObjectDelay = interObjectDelay;
41 | }
42 |
43 | @Override
44 | public List getViewListWithTimeOffsets(ViewGroup parent, List children) {
45 | List childTimedViews = new ArrayList<>();
46 | long currentTimeOffset = 0L;
47 |
48 | for (View childView : children) {
49 | childTimedViews.add(new SpruceTimedView(childView, currentTimeOffset));
50 | currentTimeOffset += interObjectDelay;
51 | }
52 |
53 | return childTimedViews;
54 | }
55 |
56 | @Override
57 | public void sortChildren(ViewGroup parent, List children) {
58 | // Do nothing, as the original order is maintained
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/sort/InlineSort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.graphics.PointF;
26 | import android.view.View;
27 | import android.view.ViewGroup;
28 |
29 | import java.util.ArrayList;
30 | import java.util.Collections;
31 | import java.util.Comparator;
32 | import java.util.List;
33 |
34 | public class InlineSort extends CorneredSort {
35 |
36 | private final long interObjectDelay;
37 | private final boolean reversed;
38 |
39 | /**
40 | * Animate child views from side to side (based on the provided corner parameter).
41 | *
42 | * @param interObjectDelay long delay between objects
43 | * @param reversed boolean indicating if the selection is reversed
44 | * @param corner {@link com.willowtreeapps.spruce.sort.CorneredSort.Corner Corner} value to start from
45 | */
46 | public InlineSort(long interObjectDelay, boolean reversed, Corner corner) {
47 | super(interObjectDelay, reversed, corner);
48 | this.interObjectDelay = interObjectDelay;
49 | this.reversed = reversed;
50 | }
51 |
52 | @Override
53 | public List getViewListWithTimeOffsets(ViewGroup parent, List children) {
54 | List timedViews = new ArrayList<>();
55 | long currentTimeOffset = 0;
56 |
57 | if (reversed) {
58 | Collections.reverse(children);
59 | }
60 |
61 | for (View view : children) {
62 | timedViews.add(new SpruceTimedView(view, currentTimeOffset));
63 | currentTimeOffset += interObjectDelay;
64 | }
65 |
66 | return timedViews;
67 | }
68 |
69 | @Override
70 | public void sortChildren(ViewGroup parent, List children) {
71 | final PointF comparisonPoint = getDistancePoint(parent, children);
72 | Collections.sort(children, new Comparator() {
73 | @Override
74 | public int compare(View left, View right) {
75 | double leftHorizontalDistance = Utils.horizontalDistance(comparisonPoint, Utils.viewToPoint(left));
76 | double leftVerticalDistance = Utils.verticalDistance(comparisonPoint, Utils.viewToPoint(left));
77 | double rightHorizontalDistance = Utils.horizontalDistance(comparisonPoint, Utils.viewToPoint(right));
78 | double rightVerticalDistance = Utils.verticalDistance(comparisonPoint, Utils.viewToPoint(right));
79 |
80 | if (leftVerticalDistance < rightVerticalDistance ||
81 | leftVerticalDistance == rightVerticalDistance &&
82 | leftHorizontalDistance < rightHorizontalDistance) {
83 | return -1;
84 | }
85 | return 1;
86 | }
87 | });
88 | }
89 |
90 | }
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/sort/LinearSort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.graphics.PointF;
26 | import android.view.View;
27 | import android.view.ViewGroup;
28 |
29 | import java.util.List;
30 |
31 | public class LinearSort extends DistancedSort {
32 |
33 | private final Direction direction;
34 |
35 | public enum Direction {
36 | TOP_TO_BOTTOM,
37 | BOTTOM_TO_TOP,
38 | LEFT_TO_RIGHT,
39 | RIGHT_TO_LEFT
40 | }
41 |
42 | /**
43 | * Establishes the delay between object animations and their direction based on distance,
44 | * delay, and a value from the Direction enum
45 | * @param interObjectDelay delay between object animations
46 | * @param reversed flag to indicate if the animation should be reversed
47 | * @param direction enum value of the direction the animation should start from and end with
48 | */
49 | public LinearSort(long interObjectDelay, boolean reversed, Direction direction) {
50 | super(interObjectDelay, reversed);
51 | if (direction == null) {
52 | throw new NullPointerException("Direction can't be null and must be of a valid type");
53 | }
54 | this.direction = direction;
55 | }
56 |
57 | @Override
58 | public PointF getDistancePoint(ViewGroup parent, List children) {
59 | PointF point = super.getDistancePoint(parent, children);
60 | switch (direction) {
61 | case TOP_TO_BOTTOM:
62 | return new PointF(parent.getWidth() / 2.0F, 0F);
63 | case BOTTOM_TO_TOP:
64 | return new PointF(parent.getWidth() / 2.0F, parent.getHeight());
65 | case LEFT_TO_RIGHT:
66 | return new PointF(0F, parent.getHeight() / 2.0F);
67 | case RIGHT_TO_LEFT:
68 | return new PointF(parent.getWidth(), parent.getHeight() / 2.0F);
69 | default:
70 | throw new AssertionError("Must be a valid Direction argument type");
71 | }
72 | }
73 |
74 | @Override
75 | public double getDistanceBetweenPoints(PointF left, PointF right) {
76 | switch (direction) {
77 | case BOTTOM_TO_TOP:
78 | case TOP_TO_BOTTOM:
79 | left.x = 0F;
80 | right.x = 0F;
81 | break;
82 | case LEFT_TO_RIGHT:
83 | case RIGHT_TO_LEFT:
84 | left.y = 0F;
85 | right.y = 0F;
86 | break;
87 | }
88 | return Utils.euclideanDistance(left, right);
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/sort/RadialSort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.graphics.PointF;
26 | import android.view.View;
27 | import android.view.ViewGroup;
28 |
29 | import java.util.List;
30 |
31 | public class RadialSort extends DistancedSort {
32 |
33 | private final Position position;
34 |
35 | public enum Position {
36 | TOP_LEFT,
37 | TOP_MIDDLE,
38 | TOP_RIGHT,
39 | LEFT,
40 | MIDDLE,
41 | RIGHT,
42 | BOTTOM_LEFT,
43 | BOTTOM_MIDDLE,
44 | BOTTOM_RIGHT
45 | }
46 |
47 | /**
48 | * Establishes the delay between object animations and their starting position based on distance,
49 | * delay, and a value from the Position enum
50 | *
51 | * @param interObjectDelay delay between object animations
52 | * @param reversed flag to indicate if the animation should be reversed
53 | * @param position enum value of the position the animation should start from
54 | */
55 | public RadialSort(long interObjectDelay, boolean reversed, Position position) {
56 | super(interObjectDelay, reversed);
57 | if (position == null) {
58 | throw new NullPointerException("Position can't be null and must be a valid type");
59 | }
60 | this.position = position;
61 | }
62 |
63 | @Override
64 | public PointF getDistancePoint(ViewGroup parent, List children) {
65 | PointF distancePoint;
66 |
67 | switch (position) {
68 | case TOP_LEFT:
69 | distancePoint = new PointF(0, 0);
70 | break;
71 | case TOP_MIDDLE:
72 | distancePoint = new PointF(parent.getWidth() / 2, 0);
73 | break;
74 | case TOP_RIGHT:
75 | distancePoint = new PointF(parent.getWidth(), 0);
76 | break;
77 | case LEFT:
78 | distancePoint = new PointF(0, parent.getHeight() / 2);
79 | break;
80 | case MIDDLE:
81 | distancePoint = new PointF(parent.getWidth() / 2, parent.getHeight() / 2);
82 | break;
83 | case RIGHT:
84 | distancePoint = new PointF(parent.getWidth(), parent.getHeight() / 2);
85 | break;
86 | case BOTTOM_LEFT:
87 | distancePoint = new PointF(0, parent.getHeight());
88 | break;
89 | case BOTTOM_MIDDLE:
90 | distancePoint = new PointF(parent.getWidth() / 2, parent.getHeight());
91 | break;
92 | case BOTTOM_RIGHT:
93 | distancePoint = new PointF(parent.getWidth(), parent.getHeight());
94 | break;
95 | default:
96 | throw new AssertionError("Must be a valid Position argument type");
97 | }
98 |
99 | return super.translate(distancePoint, children);
100 | }
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/sort/RandomSort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 |
28 | import java.util.ArrayList;
29 | import java.util.Collections;
30 | import java.util.List;
31 |
32 | public class RandomSort extends SortFunction {
33 |
34 | private final long interObjectDelay;
35 |
36 | /**
37 | * Random sort pattern that utilizes {@link Collections#shuffle(List) shuffle()}
38 | *
39 | * @param interObjectDelay
40 | */
41 | public RandomSort(long interObjectDelay) {
42 | this.interObjectDelay = interObjectDelay;
43 | }
44 |
45 | @Override
46 | public List getViewListWithTimeOffsets(ViewGroup parent, List children) {
47 | List timedViews = new ArrayList<>();
48 | long currentTimeOffset = 0;
49 |
50 | for (View view : children) {
51 | timedViews.add(new SpruceTimedView(view, currentTimeOffset));
52 | currentTimeOffset += interObjectDelay;
53 | }
54 |
55 | return timedViews;
56 | }
57 |
58 | @Override
59 | public void sortChildren(ViewGroup parent, List children) {
60 | Collections.shuffle(children);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/sort/SnakeSort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.graphics.PointF;
26 | import android.view.View;
27 | import android.view.ViewGroup;
28 |
29 | import java.util.ArrayList;
30 | import java.util.Collections;
31 | import java.util.Comparator;
32 | import java.util.List;
33 |
34 | public class SnakeSort extends CorneredSort {
35 |
36 | private final long interObjectDelay;
37 | private final boolean reversed;
38 |
39 | /**
40 | * Animate child views from side to side (based on the provided corner parameter), alternating left to right and right to left on each row.
41 | *
42 | * @param interObjectDelay long delay between objects
43 | * @param reversed boolean indicating if the selection is reversed
44 | * @param corner {@link com.willowtreeapps.spruce.sort.CorneredSort.Corner Corner} value to start from
45 | */
46 | public SnakeSort(long interObjectDelay, boolean reversed, Corner corner) {
47 | super(interObjectDelay, reversed, corner);
48 | this.interObjectDelay = interObjectDelay;
49 | this.reversed = reversed;
50 | }
51 |
52 | @Override
53 | public List getViewListWithTimeOffsets(ViewGroup parent, List children) {
54 | final PointF comparisonPoint = getDistancePoint(parent, children);
55 | List timedViews = new ArrayList<>();
56 | long currentTimeOffset = 0;
57 |
58 | // Calculate all possible vertical distances from the point of comparison.
59 | final List verticalDistances = new ArrayList<>();
60 | for (View child: children) {
61 | float d = Utils.verticalDistance(comparisonPoint, Utils.viewToPoint(child));
62 | if (!verticalDistances.contains(d)) {
63 | verticalDistances.add(d);
64 | }
65 | }
66 |
67 | // Sort these so we can find the row index by the vertical distance.
68 | Collections.sort(verticalDistances);
69 |
70 | Collections.sort(children, new Comparator() {
71 | @Override
72 | public int compare(View left, View right) {
73 | double leftHorizontalDistance = Utils.horizontalDistance(comparisonPoint, Utils.viewToPoint(left));
74 | double leftVerticalDistance = Utils.verticalDistance(comparisonPoint, Utils.viewToPoint(left));
75 | double rightHorizontalDistance = Utils.horizontalDistance(comparisonPoint, Utils.viewToPoint(right));
76 | double rightVerticalDistance = Utils.verticalDistance(comparisonPoint, Utils.viewToPoint(right));
77 |
78 | // Difference in vertical distance takes priority.
79 | if (leftVerticalDistance < rightVerticalDistance) {
80 | return -1;
81 | } else if (leftVerticalDistance > rightVerticalDistance) {
82 | return 1;
83 | }
84 |
85 | // If the are in the same row, find the row index.
86 | int row = verticalDistances.indexOf((float) leftVerticalDistance);
87 | if (leftHorizontalDistance < rightHorizontalDistance) {
88 | return row % 2 == 0 ? -1: 1;
89 | } else {
90 | return row % 2 == 0 ? 1: -1;
91 | }
92 | }
93 | });
94 |
95 | if (reversed) {
96 | Collections.reverse(children);
97 | }
98 |
99 | for (View view : children) {
100 | timedViews.add(new SpruceTimedView(view, currentTimeOffset));
101 | currentTimeOffset += interObjectDelay;
102 | }
103 |
104 | return timedViews;
105 | }
106 |
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/sort/SortFunction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 |
28 | import java.util.List;
29 |
30 | public abstract class SortFunction {
31 |
32 | /**
33 | * Sorts the children that will be animated in the view.
34 | *
35 | * @param parent ViewGroup parent of the collection of child views.
36 | * @param children The children to be sorted
37 | */
38 | public abstract void sortChildren(ViewGroup parent, List children);
39 |
40 | /**
41 | * Get a list of SpruceTimedView
42 | *
43 | * @param parent ViewGroup parent of the collection of child views
44 | * @param children List of views to be animated
45 | * @return List of SpruceTimedView objects that contain the view and it's offset
46 | */
47 | public abstract List getViewListWithTimeOffsets(ViewGroup parent, List children);
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/sort/SpruceTimedView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.view.View;
26 |
27 | public class SpruceTimedView {
28 |
29 | private final View view;
30 | private final long timeOffset;
31 |
32 | public SpruceTimedView(View view, long timeOffset) {
33 | this.view = view;
34 | this.timeOffset = timeOffset;
35 | }
36 |
37 | public View getView() {
38 | return view;
39 | }
40 |
41 | public long getTimeOffset() {
42 | return timeOffset;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/willowtreeapps/spruce/sort/Utils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.graphics.PointF;
26 | import android.view.View;
27 |
28 | import java.util.List;
29 |
30 | /**
31 | * Utility class for distance calculations and view to point conversion
32 | */
33 | class Utils {
34 |
35 | /**
36 | * Get the euclidean distance between two points
37 | *
38 | * @param firstPoint PointF object
39 | * @param secondPoint PointF object
40 | * @return float value representing the distance in a straight line between two points
41 | */
42 | public static float euclideanDistance(PointF firstPoint, PointF secondPoint) {
43 | return PointF.length(secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y);
44 | }
45 |
46 | /**
47 | * Get the horizontal, or x distance between two points
48 | *
49 | * @param firstPoint PointF object
50 | * @param secondPoint PointF object
51 | * @return float value representing the horizontal (or x) distance between two points
52 | */
53 | public static float horizontalDistance(PointF firstPoint, PointF secondPoint) {
54 | return Math.abs(secondPoint.x - firstPoint.x);
55 | }
56 |
57 | /**
58 | * Get the vertical, or y distance between two points
59 | *
60 | * @param firstPoint PointF object
61 | * @param secondPoint PointF object
62 | * @return float value representing the vertical (or y) distance between two points
63 | */
64 | public static float verticalDistance(PointF firstPoint, PointF secondPoint) {
65 | return Math.abs(secondPoint.y - firstPoint.y);
66 | }
67 |
68 | /**
69 | * Convert a view into it's coordinates as a Point
70 | *
71 | * @param view Object
72 | * @return PointF containing the x, y coordinates of the view
73 | */
74 | public static PointF viewToPoint(View view) {
75 | return new PointF(Math.round(view.getX()), Math.round(view.getY()));
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/lib/src/main/res/layout/anim_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
21 |
22 |
25 |
26 |
30 |
31 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/willowtreeapps/spruce/exclusion/ExclusionHelperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.exclusion;
24 |
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 |
28 | import org.junit.Assert;
29 | import org.junit.Before;
30 | import org.junit.Test;
31 | import org.junit.runner.RunWith;
32 | import org.mockito.Mockito;
33 | import org.robolectric.RobolectricTestRunner;
34 |
35 | import java.util.ArrayList;
36 | import java.util.List;
37 |
38 |
39 | @RunWith(RobolectricTestRunner.class)
40 | public class ExclusionHelperTest {
41 |
42 | private ViewGroup mockParent;
43 |
44 | @Before
45 | public void setup() {
46 | mockParent = Mockito.mock(ViewGroup.class);
47 | }
48 |
49 | @Test
50 | public void test_normal_exclusion_with_empty_list() {
51 | ExclusionHelper helper = new ExclusionHelper();
52 | List idList = new ArrayList<>();
53 | helper.initialize(idList, ExclusionHelper.NORMAL_MODE);
54 | Assert.assertEquals(helper.filterViews(mockParent).size(), idList.size());
55 | Assert.assertNotEquals(helper.filterViews(mockParent).size(), 1);
56 |
57 | }
58 |
59 | @Test
60 | public void test_r_l_exclusion_with_empty_list() {
61 | ExclusionHelper helper = new ExclusionHelper();
62 | List idList = new ArrayList<>();
63 | helper.initialize(idList, ExclusionHelper.R_L_MODE);
64 | Assert.assertEquals(helper.filterViews(mockParent).size(), idList.size());
65 | Assert.assertNotEquals(helper.filterViews(mockParent).size(), 1);
66 |
67 | }
68 |
69 |
70 | @Test
71 | public void test_normal_exclusion_success() {
72 | ExclusionHelper helper = new ExclusionHelper();
73 | List idList = new ArrayList<>();
74 | idList.add(2);
75 | idList.add(7);
76 | helper.initialize(idList, ExclusionHelper.NORMAL_MODE);
77 | ExclusionTestHelper.addViews(mockParent, 1, 2, 5, 7, 9);
78 | Assert.assertNotEquals(helper.filterViews(mockParent).size(), idList.size());
79 | Assert.assertEquals(helper.filterViews(mockParent).size(), idList.size() + 1);
80 |
81 | for (View view : helper.filterViews(mockParent)) {
82 | Assert.assertFalse(idList.contains(view.getId()));
83 | }
84 | }
85 |
86 | @Test
87 | public void test_r_l_exclusion_success() {
88 | ExclusionHelper helper = new ExclusionHelper();
89 | List idList = new ArrayList<>();
90 | idList.add(5);
91 | idList.add(7);
92 |
93 | List positionList = new ArrayList<>();
94 | positionList.add(2);
95 | positionList.add(3);
96 |
97 |
98 | helper.initialize(positionList, ExclusionHelper.R_L_MODE);
99 | ExclusionTestHelper.addViews(mockParent, 1, 2, 5, 7, 9);
100 | Assert.assertNotEquals(helper.filterViews(mockParent).size(), idList.size());
101 | Assert.assertEquals(helper.filterViews(mockParent).size(), idList.size() + 1);
102 |
103 | for (View view : helper.filterViews(mockParent)) {
104 | Assert.assertFalse(idList.contains(view.getId()));
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/willowtreeapps/spruce/exclusion/ExclusionTestHelper.java:
--------------------------------------------------------------------------------
1 | package com.willowtreeapps.spruce.exclusion;
2 |
3 | import android.view.View;
4 | import android.view.ViewGroup;
5 |
6 | import org.mockito.Mockito;
7 |
8 | public class ExclusionTestHelper {
9 | /**
10 | * This function creates a view groups according to the ids passed.
11 | *
12 | * @param viewGroup parent view group
13 | * @param ids id array.
14 | */
15 | static void addViews(ViewGroup viewGroup, int... ids) {
16 | Mockito.when(viewGroup.getChildCount()).thenReturn(ids.length);
17 |
18 | for (int i = 0; i < ids.length; i++) {
19 | View mockView = Mockito.mock(View.class);
20 | Mockito.when(mockView.getId()).thenReturn(ids[i]);
21 | Mockito.when(viewGroup.getChildAt(i)).thenReturn(mockView);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/willowtreeapps/spruce/sort/ContinuousSortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 |
28 | import org.junit.Assert;
29 | import org.junit.Before;
30 | import org.junit.Test;
31 | import org.junit.runner.RunWith;
32 | import org.mockito.Mockito;
33 | import org.robolectric.RobolectricTestRunner;
34 |
35 | import java.util.List;
36 |
37 | @RunWith(RobolectricTestRunner.class)
38 | public class ContinuousSortTest {
39 |
40 | private ViewGroup mockParent = Mockito.mock(ViewGroup.class);
41 | private List mockChildren;
42 |
43 | @Before
44 | public void setup() {
45 | mockChildren = TestHelper.setupMockChildren();
46 | }
47 |
48 | @Test
49 | public void test_positive_inter_object_delay() {
50 | List resultViews = new ContinuousSort(/*interObjectDelay=*/1,
51 | /*reversed=*/false,
52 | RadialSort.Position.TOP_LEFT)
53 | .getViewListWithTimeOffsets(mockParent, mockChildren);
54 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
55 | Assert.assertEquals(1, resultViews.get(1).getTimeOffset());
56 | Assert.assertEquals(1, resultViews.get(2).getTimeOffset());
57 | }
58 |
59 | @Test
60 | public void test_positive_inter_object_delay_with_reversed() {
61 | List resultViews = new ContinuousSort(/*interObjectDelay=*/1,
62 | /*reversed=*/true,
63 | RadialSort.Position.TOP_LEFT)
64 | .getViewListWithTimeOffsets(mockParent, mockChildren);
65 | Assert.assertEquals(1, resultViews.get(0).getTimeOffset());
66 | Assert.assertEquals(1, resultViews.get(1).getTimeOffset());
67 | Assert.assertEquals(0, resultViews.get(2).getTimeOffset());
68 | }
69 |
70 | @Test
71 | public void test_inter_object_delay_of_zero() {
72 | List resultViews = new ContinuousSort(/*interObjectDelay=*/0,
73 | /*reversed=*/false,
74 | RadialSort.Position.TOP_LEFT)
75 | .getViewListWithTimeOffsets(mockParent, mockChildren);
76 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
77 | Assert.assertEquals(0, resultViews.get(1).getTimeOffset());
78 | Assert.assertEquals(0, resultViews.get(2).getTimeOffset());
79 | }
80 |
81 | @Test
82 | public void test_negative_inter_object_delay() {
83 | List resultViews = new ContinuousSort(/*interObjectDelay=*/-1,
84 | /*reversed=*/false,
85 | RadialSort.Position.TOP_LEFT)
86 | .getViewListWithTimeOffsets(mockParent, mockChildren);
87 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
88 | Assert.assertEquals(0, resultViews.get(1).getTimeOffset());
89 | Assert.assertEquals(-1, resultViews.get(2).getTimeOffset());
90 | }
91 |
92 | @Test
93 | public void test_negative_inter_object_delay_with_reversed() {
94 | List resultViews = new ContinuousSort(/*interObjectDelay=*/-1,
95 | /*reversed=*/true,
96 | RadialSort.Position.TOP_LEFT)
97 | .getViewListWithTimeOffsets(mockParent, mockChildren);
98 | Assert.assertEquals(-1, resultViews.get(0).getTimeOffset());
99 | Assert.assertEquals(0, resultViews.get(1).getTimeOffset());
100 | Assert.assertEquals(0, resultViews.get(2).getTimeOffset());
101 | }
102 | }
--------------------------------------------------------------------------------
/lib/src/test/java/com/willowtreeapps/spruce/sort/DefaultSortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 |
28 | import org.junit.Assert;
29 | import org.junit.Before;
30 | import org.junit.Test;
31 | import org.junit.runner.RunWith;
32 | import org.mockito.Mockito;
33 | import org.robolectric.RobolectricTestRunner;
34 |
35 | import java.util.List;
36 |
37 | @RunWith(RobolectricTestRunner.class)
38 | public class DefaultSortTest {
39 |
40 | private ViewGroup mockParent;
41 | private List mockChildren;
42 |
43 | @Before
44 | public void setup() {
45 | mockParent = Mockito.mock(ViewGroup.class);
46 | mockChildren = TestHelper.setupMockChildren();
47 | }
48 |
49 | @Test
50 | public void test_inter_object_delay_of_views_is_set_on_default_sort() {
51 | List resultViews = new DefaultSort(/*interObjectDelay=*/1)
52 | .getViewListWithTimeOffsets(mockParent, mockChildren);
53 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
54 | Assert.assertEquals(1, resultViews.get(1).getTimeOffset());
55 | Assert.assertEquals(2, resultViews.get(2).getTimeOffset());
56 | }
57 |
58 | @Test
59 | public void test_inter_object_delay_of_zero() {
60 | List resultViews = new DefaultSort(/*interObjectDelay=*/0)
61 | .getViewListWithTimeOffsets(mockParent, mockChildren);
62 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
63 | Assert.assertEquals(0, resultViews.get(1).getTimeOffset());
64 | Assert.assertEquals(0, resultViews.get(2).getTimeOffset());
65 | }
66 |
67 | @Test
68 | public void test_negative_inter_object_delay() {
69 | List resultViews = new DefaultSort(/*interObjectDelay=*/-1)
70 | .getViewListWithTimeOffsets(mockParent, mockChildren);
71 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
72 | Assert.assertEquals(-1, resultViews.get(1).getTimeOffset());
73 | Assert.assertEquals(-2, resultViews.get(2).getTimeOffset());
74 | }
75 |
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/willowtreeapps/spruce/sort/DistancedSortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.graphics.PointF;
26 | import android.view.View;
27 | import android.view.ViewGroup;
28 |
29 | import org.hamcrest.CoreMatchers;
30 | import org.junit.Assert;
31 | import org.junit.Before;
32 | import org.junit.Test;
33 | import org.junit.runner.RunWith;
34 | import org.mockito.Mockito;
35 | import org.robolectric.RobolectricTestRunner;
36 |
37 | import java.util.ArrayList;
38 | import java.util.List;
39 |
40 | @RunWith(RobolectricTestRunner.class)
41 | public class DistancedSortTest {
42 |
43 | private ViewGroup mockParent;
44 | private List mockChildren;
45 |
46 | @Before
47 | public void setup() {
48 | mockParent = Mockito.mock(ViewGroup.class);
49 | mockChildren = TestHelper.setupMockChildren();
50 | }
51 |
52 | @Test
53 | public void test_positive_inter_object_delay() {
54 | List resultViews = new DistancedSort(/*interObjectDelay=*/1,
55 | /*reversed=*/false)
56 | .getViewListWithTimeOffsets(mockParent, mockChildren);
57 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
58 | Assert.assertEquals(1, resultViews.get(1).getTimeOffset());
59 | Assert.assertEquals(2, resultViews.get(2).getTimeOffset());
60 | }
61 |
62 | @Test
63 | public void test_inter_object_delay_of_zero() {
64 | List resultViews = new DistancedSort(/*interObjectDelay=*/0,
65 | /*reversed=*/false)
66 | .getViewListWithTimeOffsets(mockParent, mockChildren);
67 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
68 | Assert.assertEquals(0, resultViews.get(1).getTimeOffset());
69 | Assert.assertEquals(0, resultViews.get(2).getTimeOffset());
70 | }
71 |
72 | @Test
73 | public void test_negative_inter_object_delay() {
74 | List resultViews = new DistancedSort(/*interObjectDelay=*/-1,
75 | /*reversed=*/false)
76 | .getViewListWithTimeOffsets(mockParent, mockChildren);
77 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
78 | Assert.assertEquals(-1, resultViews.get(1).getTimeOffset());
79 | Assert.assertEquals(-2, resultViews.get(2).getTimeOffset());
80 | }
81 |
82 | @Test
83 | public void test_get_distance_point_returns_a_point() {
84 | ViewGroup mockParent = Mockito.mock(ViewGroup.class);
85 | List mockChildren = new ArrayList<>();
86 | mockChildren.add(Mockito.mock(View.class));
87 |
88 | DistancedSort distancedSort = new DistancedSort(/*interObjectDelay=*/0, /*reversed=*/false);
89 | Assert.assertThat(distancedSort.getDistancePoint(mockParent, mockChildren), CoreMatchers.instanceOf(PointF.class));
90 | }
91 |
92 | @Test
93 | public void test_translate_returns_a_point() {
94 | List mockChildren = new ArrayList<>();
95 | mockChildren.add(Mockito.mock(View.class));
96 |
97 | DistancedSort distancedSort = new DistancedSort(/*interObjectDelay=*/0, /*reversed=*/false);
98 | Assert.assertThat(distancedSort.translate(new PointF(0, 0), mockChildren), CoreMatchers.instanceOf(PointF.class));
99 | }
100 |
101 | @Test
102 | public void test_get_distance_between_points_returns_a_double() {
103 | DistancedSort distancedSort = new DistancedSort(/*interObjectDelay=*/0, /*reversed=*/false);
104 | PointF firstPoint = Mockito.mock(PointF.class);
105 | PointF secondPoint = Mockito.mock(PointF.class);
106 |
107 | Assert.assertThat(distancedSort.getDistanceBetweenPoints(firstPoint, secondPoint), CoreMatchers.instanceOf(Double.class));
108 | }
109 |
110 | @Test
111 | public void test_get_view_list_with_time_offsets_returns_correct_number_of_children() {
112 | ViewGroup mockParent = Mockito.mock(ViewGroup.class);
113 | List mockChildren = new ArrayList<>();
114 | for (int i = 0; i < 3; i++) {
115 | mockChildren.add(Mockito.mock(View.class));
116 | }
117 | List resultViews = new DistancedSort(/*interObjectDelay=*/0, /*reversed=*/false).getViewListWithTimeOffsets(mockParent, mockChildren);
118 | Assert.assertEquals(mockChildren.size(), resultViews.size());
119 | }
120 |
121 | }
--------------------------------------------------------------------------------
/lib/src/test/java/com/willowtreeapps/spruce/sort/InlineSortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 |
28 | import org.junit.Assert;
29 | import org.junit.Before;
30 | import org.junit.Test;
31 | import org.junit.runner.RunWith;
32 | import org.mockito.Mockito;
33 | import org.robolectric.RobolectricTestRunner;
34 |
35 | import java.util.List;
36 |
37 | @RunWith(RobolectricTestRunner.class)
38 | public class InlineSortTest {
39 |
40 | private ViewGroup mockParent;
41 | private List mockChildren;
42 |
43 | @Before
44 | public void setup() {
45 | mockParent = Mockito.mock(ViewGroup.class);
46 | mockChildren = TestHelper.setupMockChildren();
47 | }
48 |
49 | @Test
50 | public void test_positive_inter_object_delay() {
51 | List resultViews = new InlineSort(/*interObjectDelay=*/1,
52 | /*reversed=*/false,
53 | CorneredSort.Corner.BOTTOM_RIGHT)
54 | .getViewListWithTimeOffsets(mockParent, mockChildren);
55 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
56 | Assert.assertEquals(1, resultViews.get(1).getTimeOffset());
57 | Assert.assertEquals(2, resultViews.get(2).getTimeOffset());
58 | }
59 |
60 | @Test
61 | public void test_inter_object_delay_of_zero() {
62 | List resultViews = new InlineSort(/*interObjectDelay=*/0,
63 | /*reversed=*/false,
64 | CorneredSort.Corner.BOTTOM_RIGHT)
65 | .getViewListWithTimeOffsets(mockParent, mockChildren);
66 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
67 | Assert.assertEquals(0, resultViews.get(1).getTimeOffset());
68 | Assert.assertEquals(0, resultViews.get(2).getTimeOffset());
69 | }
70 |
71 | @Test
72 | public void test_negative_inter_object_delay() {
73 | List resultViews = new InlineSort(/*interObjectDelay=*/-1,
74 | /*reversed=*/false,
75 | CorneredSort.Corner.BOTTOM_RIGHT)
76 | .getViewListWithTimeOffsets(mockParent, mockChildren);
77 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
78 | Assert.assertEquals(-1, resultViews.get(1).getTimeOffset());
79 | Assert.assertEquals(-2, resultViews.get(2).getTimeOffset());
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/willowtreeapps/spruce/sort/RandomSortTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 |
28 | import org.junit.Assert;
29 | import org.junit.Before;
30 | import org.junit.Test;
31 | import org.junit.runner.RunWith;
32 | import org.mockito.Mockito;
33 | import org.robolectric.RobolectricTestRunner;
34 |
35 | import java.util.List;
36 |
37 | @RunWith(RobolectricTestRunner.class)
38 | public class RandomSortTest {
39 |
40 | private ViewGroup mockParent = Mockito.mock(ViewGroup.class);
41 | private List mockChildren;
42 |
43 | @Before
44 | public void setup() {
45 | mockChildren = TestHelper.setupMockChildren();
46 | }
47 |
48 | @Test
49 | public void test_positive_inter_object_delay() {
50 | List resultViews = new RandomSort(/*interObjectDelay=*/1)
51 | .getViewListWithTimeOffsets(mockParent, mockChildren);
52 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
53 | Assert.assertEquals(1, resultViews.get(1).getTimeOffset());
54 | Assert.assertEquals(2, resultViews.get(2).getTimeOffset());
55 | }
56 |
57 | @Test
58 | public void test_inter_object_delay_of_zero() {
59 | List resultViews = new RandomSort(/*interObjectDelay=*/0)
60 | .getViewListWithTimeOffsets(mockParent, mockChildren);
61 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
62 | Assert.assertEquals(0, resultViews.get(1).getTimeOffset());
63 | Assert.assertEquals(0, resultViews.get(2).getTimeOffset());
64 | }
65 |
66 | @Test
67 | public void test_negative_inter_object_delay() {
68 | List resultViews = new RandomSort(/*interObjectDelay=*/-1)
69 | .getViewListWithTimeOffsets(mockParent, mockChildren);
70 | Assert.assertEquals(0, resultViews.get(0).getTimeOffset());
71 | Assert.assertEquals(-1, resultViews.get(1).getTimeOffset());
72 | Assert.assertEquals(-2, resultViews.get(2).getTimeOffset());
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/lib/src/test/java/com/willowtreeapps/spruce/sort/ShadowPointF.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.graphics.PointF;
26 |
27 | import android.graphics.Point;
28 |
29 | import org.robolectric.annotation.Implements;
30 | import org.robolectric.annotation.Implementation;
31 | import org.robolectric.annotation.RealObject;
32 |
33 | /**
34 | * Shadow implementation of {@code PointF}
35 | */
36 | @SuppressWarnings({"UnusedDeclaration"})
37 | @Implements(PointF.class)
38 | public class ShadowPointF {
39 | @RealObject private PointF realPointF;
40 |
41 | public void __constructor__(float x, float y) {
42 | realPointF.x = x;
43 | realPointF.y = y;
44 | }
45 |
46 | public void __constructor__(Point src) {
47 | realPointF.x = src.x;
48 | realPointF.y = src.y;
49 | }
50 |
51 | @Implementation
52 | public void set(float x, float y) {
53 | realPointF.x = x;
54 | realPointF.y = y;
55 | }
56 |
57 | @Implementation
58 | public final void negate() {
59 | realPointF.x = -realPointF.x;
60 | realPointF.y = -realPointF.y;
61 | }
62 |
63 | @Implementation
64 | public final void offset(float dx, float dy) {
65 | realPointF.x += dx;
66 | realPointF.y += dy;
67 | }
68 |
69 | @Override @Implementation
70 | public boolean equals(Object object) {
71 | if (object == null) return false;
72 | if (this == object) return true;
73 | if (object.getClass() != PointF.class) return false;
74 |
75 | PointF that = (PointF) object;
76 | if (this.realPointF.x == that.x && this.realPointF.y == that.y) return true;
77 |
78 | return false;
79 | }
80 |
81 | @Override @Implementation
82 | public int hashCode() {
83 | return (int) (realPointF.x * 32713 + realPointF.y);
84 | }
85 |
86 | @Override @Implementation
87 | public String toString() {
88 | return "Point(" + realPointF.x + ", " + realPointF.y + ")";
89 | }
90 |
91 | /**
92 | * Non-Android utility method for comparing a point to a well-known value
93 | *
94 | * @param x x
95 | * @param y y
96 | * @return this.x == x && this.y == y
97 | */
98 | @Implementation
99 | public final boolean equals(float x, float y) {
100 | return realPointF.x == x && realPointF.y == y;
101 | }
102 | }
--------------------------------------------------------------------------------
/lib/src/test/java/com/willowtreeapps/spruce/sort/TestHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Spruce
3 | *
4 | * Copyright (c) 2017 WillowTree, Inc.
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | * THE SOFTWARE.
20 | *
21 | */
22 |
23 | package com.willowtreeapps.spruce.sort;
24 |
25 | import android.view.View;
26 |
27 | import org.mockito.Mockito;
28 |
29 | import java.util.ArrayList;
30 | import java.util.List;
31 |
32 | class TestHelper {
33 |
34 | static List setupMockChildren() {
35 | List mockChildren = new ArrayList<>();
36 | float x = 0;
37 | float y = 0;
38 | for (int i = 0; i < 3; i++) {
39 | View mockView = Mockito.mock(View.class);
40 | Mockito.when(mockView.getX()).thenReturn(x);
41 | Mockito.when(mockView.getY()).thenReturn(y);
42 | mockChildren.add(mockView);
43 | x++;
44 | y++;
45 | }
46 | return mockChildren;
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':lib', ':app'
2 |
--------------------------------------------------------------------------------