Browse Source

Refactor NavigationAnimator

Guy Carmeli 6 years ago
parent
commit
33fb8343f7

+ 0
- 6
lib/android/app/src/main/java/com/reactnativenavigation/anim/AnimationListener.java View File

@@ -1,6 +0,0 @@
1
-package com.reactnativenavigation.anim;
2
-
3
-
4
-public interface AnimationListener {
5
-    void onAnimationEnd();
6
-}

+ 8
- 7
lib/android/app/src/main/java/com/reactnativenavigation/anim/NavigationAnimator.java View File

@@ -1,6 +1,7 @@
1 1
 package com.reactnativenavigation.anim;
2 2
 
3 3
 import android.animation.Animator;
4
+import android.animation.Animator.AnimatorListener;
4 5
 import android.animation.AnimatorListenerAdapter;
5 6
 import android.animation.AnimatorSet;
6 7
 import android.content.Context;
@@ -20,7 +21,7 @@ public class NavigationAnimator extends BaseAnimator {
20 21
         this.options = options;
21 22
     }
22 23
 
23
-    public void push(final View view, AnimationListener animationListener) {
24
+    public void push(final View view, Runnable onAnimationEnd) {
24 25
         view.setVisibility(View.INVISIBLE);
25 26
         AnimatorSet set = options.push.content.getAnimation(view, getDefaultPushAnimation(view));
26 27
         set.addListener(new AnimatorListenerAdapter() {
@@ -31,26 +32,26 @@ public class NavigationAnimator extends BaseAnimator {
31 32
 
32 33
             @Override
33 34
             public void onAnimationEnd(Animator animation) {
34
-                animationListener.onAnimationEnd();
35
+                onAnimationEnd.run();
35 36
             }
36 37
         });
37 38
         set.start();
38 39
     }
39 40
 
40
-    public void pop(View view, AnimationListener animationListener) {
41
+    public void pop(View view, Runnable onAnimationEnd) {
41 42
         AnimatorSet set = options.pop.content.getAnimation(view, getDefaultPopAnimation(view));
42 43
         set.addListener(new AnimatorListenerAdapter() {
43 44
             @Override
44 45
             public void onAnimationEnd(Animator animation) {
45
-                animationListener.onAnimationEnd();
46
+                onAnimationEnd.run();
46 47
             }
47 48
         });
48 49
         set.start();
49 50
     }
50 51
 
51
-    public void animateStartApp(View view, AnimationListener animationListener) {
52
+    public void animateStartApp(View view, AnimatorListener listener) {
52 53
         view.setVisibility(View.INVISIBLE);
53
-        AnimatorSet set = options.startApp.getAnimation(view, null);
54
+        AnimatorSet set = options.startApp.getAnimation(view);
54 55
         set.addListener(new AnimatorListenerAdapter() {
55 56
             @Override
56 57
             public void onAnimationStart(Animator animation) {
@@ -59,7 +60,7 @@ public class NavigationAnimator extends BaseAnimator {
59 60
 
60 61
             @Override
61 62
             public void onAnimationEnd(Animator animation) {
62
-                if (animationListener != null) animationListener.onAnimationEnd();
63
+                listener.onAnimationEnd(animation);
63 64
             }
64 65
         });
65 66
         set.start();

+ 8
- 10
lib/android/app/src/main/java/com/reactnativenavigation/anim/TopBarAnimator.java View File

@@ -9,6 +9,7 @@ import android.animation.TimeInterpolator;
9 9
 import android.view.View;
10 10
 import android.view.animation.AccelerateInterpolator;
11 11
 import android.view.animation.DecelerateInterpolator;
12
+import android.view.animation.LinearInterpolator;
12 13
 
13 14
 import com.reactnativenavigation.parse.AnimationOptions;
14 15
 import com.reactnativenavigation.views.topbar.TopBar;
@@ -21,6 +22,7 @@ public class TopBarAnimator {
21 22
     private static final int DURATION_TOPBAR = 300;
22 23
     private final DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator();
23 24
     private final AccelerateInterpolator accelerateInterpolator = new AccelerateInterpolator();
25
+    private final LinearInterpolator linearInterpolator = new LinearInterpolator();
24 26
 
25 27
     private TopBar topBar;
26 28
     private String stackId;
@@ -46,7 +48,7 @@ public class TopBarAnimator {
46 48
     }
47 49
 
48 50
     public void show(float startTranslation) {
49
-        showAnimator = getDefaultShowAnimator(startTranslation, null, DEFAULT_COLLAPSE_DURATION);
51
+        showAnimator = getDefaultShowAnimator(startTranslation, linearInterpolator, DEFAULT_COLLAPSE_DURATION);
50 52
         show();
51 53
     }
52 54
 
@@ -69,26 +71,26 @@ public class TopBarAnimator {
69 71
         return set;
70 72
     }
71 73
 
72
-    public void hide(AnimationOptions options, AnimationListener listener) {
74
+    public void hide(AnimationOptions options, Runnable onAnimationEnd) {
73 75
         if (options.hasValue() && (!options.id.hasValue() || options.id.get().equals(stackId))) {
74 76
             hideAnimator = options.getAnimation(topBar);
75 77
         } else {
76 78
             hideAnimator = getDefaultHideAnimator(0, accelerateInterpolator, DURATION_TOPBAR);
77 79
         }
78
-        hide(listener);
80
+        hide(onAnimationEnd);
79 81
     }
80 82
 
81 83
     void hide(float startTranslation) {
82 84
         hideAnimator = getDefaultHideAnimator(startTranslation, null, DEFAULT_COLLAPSE_DURATION);
83
-        hide(null);
85
+        hide(() -> {});
84 86
     }
85 87
 
86
-    private void hide(AnimationListener listener) {
88
+    private void hide(Runnable onAnimationEnd) {
87 89
         hideAnimator.addListener(new AnimatorListenerAdapter() {
88 90
             @Override
89 91
             public void onAnimationEnd(Animator animation) {
90 92
                 topBar.setVisibility(View.GONE);
91
-                if (listener != null) listener.onAnimationEnd();
93
+                onAnimationEnd.run();
92 94
             }
93 95
         });
94 96
         hideAnimator.start();
@@ -102,8 +104,4 @@ public class TopBarAnimator {
102 104
         set.play(hideAnimator);
103 105
         return set;
104 106
     }
105
-
106
-    public boolean isRunning() {
107
-        return (hideAnimator != null && hideAnimator.isRunning()) || (showAnimator != null && showAnimator.isRunning());
108
-    }
109 107
 }

+ 4
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/AnimationOptions.java View File

@@ -61,6 +61,10 @@ public class AnimationOptions {
61 61
         return hasValue;
62 62
     }
63 63
 
64
+    public AnimatorSet getAnimation(View view) {
65
+        return getAnimation(view, null);
66
+    }
67
+
64 68
     public AnimatorSet getAnimation(View view, AnimatorSet defaultAnimation) {
65 69
         if (!hasValue()) return defaultAnimation;
66 70
         AnimatorSet animationSet = new AnimatorSet();

+ 1
- 2
lib/android/app/src/main/java/com/reactnativenavigation/presentation/OptionsPresenter.java View File

@@ -2,7 +2,6 @@ package com.reactnativenavigation.presentation;
2 2
 
3 3
 import android.app.Activity;
4 4
 import android.graphics.Color;
5
-import android.support.annotation.NonNull;
6 5
 
7 6
 import com.reactnativenavigation.interfaces.ChildDisappearListener;
8 7
 import com.reactnativenavigation.parse.AnimationsOptions;
@@ -106,7 +105,7 @@ public class OptionsPresenter {
106 105
         if (topTabOptions.fontFamily != null) topBar.setTopTabFontFamily(topTabOptions.tabIndex, topTabOptions.fontFamily);
107 106
     }
108 107
 
109
-    public void onChildWillDisappear(Options disappearing, Options appearing, @NonNull ChildDisappearListener childDisappearListener) {
108
+    public void onChildWillDisappear(Options disappearing, Options appearing, ChildDisappearListener childDisappearListener) {
110 109
         if (disappearing.topBarOptions.visible.isTrueOrUndefined() && appearing.topBarOptions.visible.isFalse()) {
111 110
             if (disappearing.topBarOptions.animate.isTrueOrUndefined()) {
112 111
                 topBar.hideAnimate(disappearing.animationsOptions.pop.topBar, childDisappearListener::childDisappear);

+ 8
- 1
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/Navigator.java View File

@@ -1,5 +1,7 @@
1 1
 package com.reactnativenavigation.viewcontrollers;
2 2
 
3
+import android.animation.Animator;
4
+import android.animation.AnimatorListenerAdapter;
3 5
 import android.app.Activity;
4 6
 import android.support.annotation.NonNull;
5 7
 import android.support.annotation.Nullable;
@@ -79,7 +81,12 @@ public class Navigator extends ParentController implements ModalListener {
79 81
         if (animationsOptions.startApp.hasValue()) {
80 82
             getView().addView(view);
81 83
             new NavigationAnimator(viewController.getActivity(), animationsOptions)
82
-                    .animateStartApp(view, () -> promise.resolve(viewController.getId()));
84
+                    .animateStartApp(view, new AnimatorListenerAdapter() {
85
+                        @Override
86
+                        public void onAnimationEnd(Animator animation) {
87
+                            promise.resolve(viewController.getId());
88
+                        }
89
+                    });
83 90
         } else {
84 91
             getView().addView(view);
85 92
             promise.resolve(viewController.getId());

+ 1
- 4
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/StackController.java View File

@@ -143,10 +143,7 @@ public class StackController extends ParentController<StackLayout> {
143 143
         );
144 144
 
145 145
         if (disappearing.options.animated.isTrueOrUndefined()) {
146
-            animator.pop(
147
-                    disappearing.getView(),
148
-                    () -> finishPopping(disappearing, listener)
149
-            );
146
+            animator.pop(disappearing.getView(), () -> finishPopping(disappearing, listener));
150 147
         } else {
151 148
             finishPopping(disappearing, listener);
152 149
         }

+ 4
- 4
lib/android/app/src/main/java/com/reactnativenavigation/views/topbar/TopBar.java View File

@@ -1,5 +1,6 @@
1 1
 package com.reactnativenavigation.views.topbar;
2 2
 
3
+import android.animation.Animator.AnimatorListener;
3 4
 import android.annotation.SuppressLint;
4 5
 import android.content.Context;
5 6
 import android.graphics.Typeface;
@@ -13,7 +14,6 @@ import android.view.View;
13 14
 import android.widget.RelativeLayout;
14 15
 import android.widget.TextView;
15 16
 
16
-import com.reactnativenavigation.anim.AnimationListener;
17 17
 import com.reactnativenavigation.anim.TopBarAnimator;
18 18
 import com.reactnativenavigation.anim.TopBarCollapseBehavior;
19 19
 import com.reactnativenavigation.interfaces.ScrollEventListener;
@@ -198,11 +198,11 @@ public class TopBar extends AppBarLayout implements ScrollEventListener.ScrollAw
198 198
     }
199 199
 
200 200
     public void hideAnimate(AnimationOptions options) {
201
-        hideAnimate(options, null);
201
+        hideAnimate(options, () -> {});
202 202
     }
203 203
 
204
-    public void hideAnimate(AnimationOptions options, AnimationListener listener) {
205
-        animator.hide(options, listener);
204
+    public void hideAnimate(AnimationOptions options, Runnable onAnimationEnd) {
205
+        animator.hide(options, onAnimationEnd);
206 206
     }
207 207
 
208 208
     @Override

+ 5
- 5
lib/android/app/src/test/java/com/reactnativenavigation/anim/ViewAnimationSetBuilderTest.java View File

@@ -22,12 +22,12 @@ public class ViewAnimationSetBuilderTest extends BaseTest {
22 22
     }
23 23
 
24 24
     @Test
25
-    public void implementsViewAnimationListener() throws Exception {
25
+    public void implementsViewAnimationListener() {
26 26
         assertThat(new ViewAnimationSetBuilder()).isInstanceOf(Animation.AnimationListener.class);
27 27
     }
28 28
 
29 29
     @Test
30
-    public void optionalCompletionListener() throws Exception {
30
+    public void optionalCompletionListener() {
31 31
         new ViewAnimationSetBuilder()
32 32
                 .add(someView(), someAnimation())
33 33
                 .start();
@@ -35,7 +35,7 @@ public class ViewAnimationSetBuilderTest extends BaseTest {
35 35
     }
36 36
 
37 37
     @Test
38
-    public void startsAllAnimations() throws Exception {
38
+    public void startsAllAnimations() {
39 39
         Animation anim1 = someAnimation();
40 40
         Animation anim2 = someAnimation();
41 41
         new ViewAnimationSetBuilder()
@@ -48,7 +48,7 @@ public class ViewAnimationSetBuilderTest extends BaseTest {
48 48
     }
49 49
 
50 50
     @Test
51
-    public void callsEndListenerOnlyAfterAllAnimationsFinish() throws Exception {
51
+    public void callsEndListenerOnlyAfterAllAnimationsFinish() {
52 52
         Animation anim1 = someAnimation();
53 53
         Animation anim2 = someAnimation();
54 54
         ViewAnimationSetBuilder uut = new ViewAnimationSetBuilder();
@@ -60,7 +60,7 @@ public class ViewAnimationSetBuilderTest extends BaseTest {
60 60
     }
61 61
 
62 62
     @Test
63
-    public void clearsAnimationFromViewsAfterFinished() throws Exception {
63
+    public void clearsAnimationFromViewsAfterFinished() {
64 64
         View v1 = someView();
65 65
         View v2 = someView();
66 66
         new ViewAnimationSetBuilder()

+ 0
- 24
lib/android/app/src/test/java/com/reactnativenavigation/mocks/TestNavigationAnimator.java View File

@@ -1,24 +0,0 @@
1
-package com.reactnativenavigation.mocks;
2
-
3
-import android.view.*;
4
-
5
-import com.reactnativenavigation.anim.*;
6
-
7
-import org.robolectric.*;
8
-
9
-public class TestNavigationAnimator extends NavigationAnimator {
10
-
11
-    public TestNavigationAnimator() {
12
-        super(RuntimeEnvironment.application);
13
-    }
14
-
15
-    @Override
16
-    public void push(final View enteringView, AnimationListener animationListener) {
17
-        if (animationListener != null) animationListener.onAnimationEnd();
18
-    }
19
-
20
-    @Override
21
-    public void pop(final View enteringView, AnimationListener animationListener) {
22
-        if (animationListener != null) animationListener.onAnimationEnd();
23
-    }
24
-}

+ 3
- 1
lib/android/app/src/test/java/com/reactnativenavigation/views/TopBarTest.java View File

@@ -23,6 +23,8 @@ import org.junit.Test;
23 23
 import java.util.ArrayList;
24 24
 
25 25
 import static org.assertj.core.api.Java6Assertions.assertThat;
26
+import static org.mockito.ArgumentMatchers.any;
27
+import static org.mockito.ArgumentMatchers.eq;
26 28
 import static org.mockito.Mockito.spy;
27 29
 import static org.mockito.Mockito.times;
28 30
 import static org.mockito.Mockito.verify;
@@ -87,7 +89,7 @@ public class TopBarTest extends BaseTest {
87 89
     public void hide_animate() {
88 90
         AnimationOptions options = new AnimationOptions();
89 91
         uut.hideAnimate(options);
90
-        verify(animator, times(1)).hide(options, null);
92
+        verify(animator, times(1)).hide(eq(options), any());
91 93
     }
92 94
 
93 95
     @Test