Daniel Zlotin 6 years ago
parent
commit
38e85f8a69

+ 14
- 16
lib/android/app/src/main/java/com/reactnativenavigation/anim/BaseAnimator.java View File

@@ -3,20 +3,24 @@ package com.reactnativenavigation.anim;
3 3
 
4 4
 import android.animation.AnimatorSet;
5 5
 import android.animation.ObjectAnimator;
6
+import android.animation.TimeInterpolator;
6 7
 import android.content.Context;
7 8
 import android.support.annotation.NonNull;
8 9
 import android.view.View;
9
-import android.view.animation.AccelerateInterpolator;
10
+import android.view.animation.AccelerateDecelerateInterpolator;
10 11
 import android.view.animation.DecelerateInterpolator;
11 12
 
12 13
 import com.reactnativenavigation.parse.AnimationsOptions;
13 14
 import com.reactnativenavigation.utils.UiUtils;
14 15
 
16
+import static android.view.View.ALPHA;
17
+import static android.view.View.TRANSLATION_Y;
18
+
15 19
 class BaseAnimator {
16 20
 
17 21
     private static final int DURATION = 300;
18
-    private static final DecelerateInterpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator();
19
-    private static final AccelerateInterpolator ACCELERATE_INTERPOLATOR = new AccelerateInterpolator();
22
+    private static final TimeInterpolator DECELERATE = new DecelerateInterpolator();
23
+    private static final TimeInterpolator ACCELERATE_DECELERATE = new AccelerateDecelerateInterpolator();
20 24
 
21 25
     protected AnimationsOptions options = new AnimationsOptions();
22 26
 
@@ -28,13 +32,11 @@ class BaseAnimator {
28 32
 
29 33
     @NonNull
30 34
     AnimatorSet getDefaultPushAnimation(View view) {
31
-        ObjectAnimator alpha = ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1);
32
-        alpha.setInterpolator(DECELERATE_INTERPOLATOR);
33
-
34 35
         AnimatorSet set = new AnimatorSet();
35
-        ObjectAnimator translationY = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, this.translationY, 0);
36
-        set.setInterpolator(DECELERATE_INTERPOLATOR);
36
+        set.setInterpolator(DECELERATE);
37 37
         set.setDuration(DURATION);
38
+        ObjectAnimator translationY = ObjectAnimator.ofFloat(view, TRANSLATION_Y, this.translationY, 0);
39
+        ObjectAnimator alpha = ObjectAnimator.ofFloat(view, ALPHA, 0, 1);
38 40
         set.playTogether(translationY, alpha);
39 41
         return set;
40 42
     }
@@ -43,14 +45,10 @@ class BaseAnimator {
43 45
     @NonNull
44 46
     AnimatorSet getDefaultPopAnimation(View view) {
45 47
         AnimatorSet set = new AnimatorSet();
46
-
47
-        ObjectAnimator alpha = ObjectAnimator.ofFloat(view, View.ALPHA, 1, 0);
48
-        alpha.setInterpolator(ACCELERATE_INTERPOLATOR);
49
-
50
-        ObjectAnimator translationY = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, 0, this.translationY);
51
-        translationY.setInterpolator(ACCELERATE_INTERPOLATOR);
52
-        translationY.setDuration(DURATION);
53
-        alpha.setDuration(DURATION);
48
+        set.setInterpolator(ACCELERATE_DECELERATE);
49
+        set.setDuration(DURATION);
50
+        ObjectAnimator translationY = ObjectAnimator.ofFloat(view, TRANSLATION_Y, 0, this.translationY);
51
+        ObjectAnimator alpha = ObjectAnimator.ofFloat(view, ALPHA, 1, 0);
54 52
         set.playTogether(translationY, alpha);
55 53
         return set;
56 54
     }

lib/android/app/src/main/java/com/reactnativenavigation/anim/ModalAnimator2.java → lib/android/app/src/main/java/com/reactnativenavigation/anim/ModalAnimator.java View File

@@ -8,11 +8,11 @@ import android.view.View;
8 8
 
9 9
 import com.reactnativenavigation.parse.AnimationOptions;
10 10
 
11
-public class ModalAnimator2 extends BaseAnimator {
11
+public class ModalAnimator extends BaseAnimator {
12 12
 
13 13
     private Animator animator;
14 14
 
15
-    public ModalAnimator2(Context context) {
15
+    public ModalAnimator(Context context) {
16 16
         super(context);
17 17
     }
18 18
 

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

@@ -7,6 +7,7 @@ import android.animation.AnimatorSet;
7 7
 import android.animation.ObjectAnimator;
8 8
 import android.animation.TimeInterpolator;
9 9
 import android.view.View;
10
+import android.view.animation.AccelerateDecelerateInterpolator;
10 11
 import android.view.animation.DecelerateInterpolator;
11 12
 import android.view.animation.LinearInterpolator;
12 13
 
@@ -15,12 +16,15 @@ import com.reactnativenavigation.views.topbar.TopBar;
15 16
 
16 17
 import javax.annotation.Nullable;
17 18
 
19
+import static android.view.View.TRANSLATION_Y;
20
+
18 21
 public class TopBarAnimator {
19 22
 
20 23
     private static final int DEFAULT_COLLAPSE_DURATION = 100;
21
-    private static final int DURATION_TOPBAR = 300;
22
-    private final DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator();
23
-    private final LinearInterpolator linearInterpolator = new LinearInterpolator();
24
+    private static final int DURATION = 300;
25
+    private static final TimeInterpolator DECELERATE = new DecelerateInterpolator();
26
+    private static final TimeInterpolator LINEAR = new LinearInterpolator();
27
+    private static final TimeInterpolator ACCELERATE_DECELERATE = new AccelerateDecelerateInterpolator();
24 28
 
25 29
     private TopBar topBar;
26 30
     private String stackId;
@@ -40,13 +44,13 @@ public class TopBarAnimator {
40 44
         if (options.hasValue() && (!options.id.hasValue() || options.id.get().equals(stackId))) {
41 45
             showAnimator = options.getAnimation(topBar);
42 46
         } else {
43
-            showAnimator = getDefaultShowAnimator(-1 * topBar.getMeasuredHeight(), decelerateInterpolator, DURATION_TOPBAR);
47
+            showAnimator = getDefaultShowAnimator(-1 * topBar.getMeasuredHeight(), DECELERATE, DURATION);
44 48
         }
45 49
         show();
46 50
     }
47 51
 
48 52
     public void show(float startTranslation) {
49
-        showAnimator = getDefaultShowAnimator(startTranslation, linearInterpolator, DEFAULT_COLLAPSE_DURATION);
53
+        showAnimator = getDefaultShowAnimator(startTranslation, LINEAR, DEFAULT_COLLAPSE_DURATION);
50 54
         show();
51 55
     }
52 56
 
@@ -62,7 +66,7 @@ public class TopBarAnimator {
62 66
     }
63 67
 
64 68
     private AnimatorSet getDefaultShowAnimator(float startTranslation, TimeInterpolator interpolator, int duration) {
65
-        ObjectAnimator showAnimator = ObjectAnimator.ofFloat(topBar, View.TRANSLATION_Y, startTranslation, 0);
69
+        ObjectAnimator showAnimator = ObjectAnimator.ofFloat(topBar, TRANSLATION_Y, startTranslation, 0);
66 70
         showAnimator.setInterpolator(interpolator);
67 71
         showAnimator.setDuration(duration);
68 72
         AnimatorSet set = new AnimatorSet();
@@ -74,13 +78,13 @@ public class TopBarAnimator {
74 78
         if (options.hasValue() && (!options.id.hasValue() || options.id.get().equals(stackId))) {
75 79
             hideAnimator = options.getAnimation(topBar);
76 80
         } else {
77
-            hideAnimator = getDefaultHideAnimator(0, linearInterpolator, DURATION_TOPBAR);
81
+            hideAnimator = getDefaultHideAnimator(0, ACCELERATE_DECELERATE, DURATION);
78 82
         }
79 83
         hide(onAnimationEnd);
80 84
     }
81 85
 
82 86
     void hide(float startTranslation) {
83
-        hideAnimator = getDefaultHideAnimator(startTranslation, linearInterpolator, DEFAULT_COLLAPSE_DURATION);
87
+        hideAnimator = getDefaultHideAnimator(startTranslation, LINEAR, DEFAULT_COLLAPSE_DURATION);
84 88
         hide(() -> {});
85 89
     }
86 90
 
@@ -96,7 +100,7 @@ public class TopBarAnimator {
96 100
     }
97 101
 
98 102
     private Animator getDefaultHideAnimator(float startTranslation, TimeInterpolator interpolator, int duration) {
99
-        ObjectAnimator hideAnimator = ObjectAnimator.ofFloat(topBar, View.TRANSLATION_Y, startTranslation, -1 * topBar.getMeasuredHeight());
103
+        ObjectAnimator hideAnimator = ObjectAnimator.ofFloat(topBar, TRANSLATION_Y, startTranslation, -1 * topBar.getMeasuredHeight());
100 104
         hideAnimator.setInterpolator(interpolator);
101 105
         hideAnimator.setDuration(duration);
102 106
         return hideAnimator;

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

@@ -9,7 +9,7 @@ import android.view.ViewGroup;
9 9
 import android.widget.FrameLayout;
10 10
 
11 11
 import com.facebook.react.bridge.Promise;
12
-import com.reactnativenavigation.anim.ModalAnimator2;
12
+import com.reactnativenavigation.anim.ModalAnimator;
13 13
 import com.reactnativenavigation.anim.NavigationAnimator;
14 14
 import com.reactnativenavigation.parse.Options;
15 15
 import com.reactnativenavigation.presentation.NavigationOptionsListener;
@@ -17,7 +17,7 @@ import com.reactnativenavigation.presentation.OverlayManager;
17 17
 import com.reactnativenavigation.utils.CommandListenerAdapter;
18 18
 import com.reactnativenavigation.utils.CompatUtils;
19 19
 import com.reactnativenavigation.viewcontrollers.modal.ModalPresenter;
20
-import com.reactnativenavigation.viewcontrollers.modal.ModalStack2;
20
+import com.reactnativenavigation.viewcontrollers.modal.ModalStack;
21 21
 
22 22
 import java.util.Collection;
23 23
 import java.util.Collections;
@@ -30,7 +30,7 @@ public class Navigator extends ParentController {
30 30
         void onError(String message);
31 31
     }
32 32
 
33
-    private final ModalStack2 modalStack;
33
+    private final ModalStack modalStack;
34 34
     private ViewController root;
35 35
     private FrameLayout rootLayout;
36 36
     private FrameLayout contentLayout;
@@ -39,7 +39,7 @@ public class Navigator extends ParentController {
39 39
 
40 40
     public Navigator(final Activity activity) {
41 41
         super(activity, "navigator" + CompatUtils.generateViewId(), new Options());
42
-        modalStack = new ModalStack2(new ModalPresenter(new ModalAnimator2(activity)));
42
+        modalStack = new ModalStack(new ModalPresenter(new ModalAnimator(activity)));
43 43
     }
44 44
 
45 45
     public FrameLayout getContentLayout() {
@@ -87,7 +87,6 @@ public class Navigator extends ParentController {
87 87
         }
88 88
 
89 89
         root = viewController;
90
-
91 90
         contentLayout.addView(viewController.getView());
92 91
         if (viewController.options.animations.startApp.hasValue()) {
93 92
             new NavigationAnimator(viewController.getActivity(), viewController.options.animations)
@@ -184,18 +183,8 @@ public class Navigator extends ParentController {
184 183
     }
185 184
 
186 185
     public void dismissModal(final String componentId, CommandListener listener) {
187
-        modalStack.dismissModal(componentId, new CommandListener() {
188
-            @Override
189
-            public void onSuccess(String childId) {
190
-                if (modalStack.size() == 0) contentLayout.addView(root.getView());
191
-                listener.onSuccess(childId);
192
-            }
193
-
194
-            @Override
195
-            public void onError(String message) {
196
-                listener.onError(message);
197
-            }
198
-        });
186
+        if (modalStack.size() == 1) contentLayout.addView(root.getView());
187
+        modalStack.dismissModal(componentId, listener);
199 188
     }
200 189
 
201 190
     public void dismissAllModals(CommandListener listener) {

+ 3
- 3
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenter.java View File

@@ -4,7 +4,7 @@ import android.animation.Animator;
4 4
 import android.animation.AnimatorListenerAdapter;
5 5
 import android.view.ViewGroup;
6 6
 
7
-import com.reactnativenavigation.anim.ModalAnimator2;
7
+import com.reactnativenavigation.anim.ModalAnimator;
8 8
 import com.reactnativenavigation.viewcontrollers.Navigator.CommandListener;
9 9
 import com.reactnativenavigation.viewcontrollers.ViewController;
10 10
 
@@ -13,9 +13,9 @@ import javax.annotation.Nullable;
13 13
 public class ModalPresenter {
14 14
 
15 15
     private ViewGroup content;
16
-    private ModalAnimator2 animator;
16
+    private ModalAnimator animator;
17 17
 
18
-    public ModalPresenter(ModalAnimator2 animator) {
18
+    public ModalPresenter(ModalAnimator animator) {
19 19
         this.animator = animator;
20 20
     }
21 21
 

lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalStack2.java → lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalStack.java View File

@@ -11,11 +11,11 @@ import java.util.List;
11 11
 
12 12
 import javax.annotation.Nullable;
13 13
 
14
-public class ModalStack2 {
14
+public class ModalStack {
15 15
     private List<ViewController> modals = new ArrayList<>();
16 16
     private final ModalPresenter presenter;
17 17
 
18
-    public ModalStack2(ModalPresenter presenter) {
18
+    public ModalStack(ModalPresenter presenter) {
19 19
         this.presenter = presenter;
20 20
     }
21 21
 

+ 16
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/NavigatorTest.java View File

@@ -412,6 +412,22 @@ public class NavigatorTest extends BaseTest {
412 412
         verify(parentController, times(2)).onViewAppeared();
413 413
     }
414 414
 
415
+    @Test
416
+    public void dismissModal_rootIsAttachedBeforeModalIsDismissed() {
417
+        disableShowModalAnimation(child1, child2);
418
+        disableDismissModalAnimation(child2);
419
+
420
+        uut.setRoot(parentController, new MockPromise());
421
+        uut.showModal(child1, new CommandListenerAdapter());
422
+        uut.showModal(child2, new CommandListenerAdapter());
423
+
424
+        uut.dismissModal(child2.getId(), new CommandListenerAdapter());
425
+        assertThat(parentController.getView().getParent()).isNull();
426
+
427
+        uut.dismissModal(child1.getId(), new CommandListenerAdapter());
428
+        assertThat(parentController.getView().getParent()).isNotNull();
429
+    }
430
+
415 431
     @Test
416 432
     public void dismissAllModals_onViewAppearedInvokedOnRoot() {
417 433
         disableShowModalAnimation(child1);

+ 2
- 2
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalAnimatorMock.java View File

@@ -4,10 +4,10 @@ import android.animation.AnimatorListenerAdapter;
4 4
 import android.content.Context;
5 5
 import android.view.View;
6 6
 
7
-import com.reactnativenavigation.anim.ModalAnimator2;
7
+import com.reactnativenavigation.anim.ModalAnimator;
8 8
 import com.reactnativenavigation.parse.AnimationOptions;
9 9
 
10
-public class ModalAnimatorMock extends ModalAnimator2 {
10
+public class ModalAnimatorMock extends ModalAnimator {
11 11
 
12 12
     ModalAnimatorMock(Context context) {
13 13
         super(context);

+ 3
- 3
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenterTest.java View File

@@ -4,7 +4,7 @@ import android.app.Activity;
4 4
 import android.widget.FrameLayout;
5 5
 
6 6
 import com.reactnativenavigation.BaseTest;
7
-import com.reactnativenavigation.anim.ModalAnimator2;
7
+import com.reactnativenavigation.anim.ModalAnimator;
8 8
 import com.reactnativenavigation.mocks.SimpleViewController;
9 9
 import com.reactnativenavigation.parse.Options;
10 10
 import com.reactnativenavigation.utils.CommandListenerAdapter;
@@ -28,12 +28,12 @@ public class ModalPresenterTest extends BaseTest {
28 28
     private ViewController modal2;
29 29
     private ModalPresenter uut;
30 30
     private FrameLayout contentLayout;
31
-    private ModalAnimator2 animator;
31
+    private ModalAnimator animator;
32 32
 
33 33
     @Override
34 34
     public void beforeEach() {
35 35
         Activity activity = newActivity();
36
-        animator = spy(new ModalAnimator2(activity));
36
+        animator = spy(new ModalAnimator(activity));
37 37
         uut = new ModalPresenter(animator);
38 38
         contentLayout = new FrameLayout(activity);
39 39
         activity.setContentView(contentLayout);

+ 4
- 4
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalStackTest2.java View File

@@ -5,7 +5,7 @@ import android.view.ViewGroup;
5 5
 import android.widget.FrameLayout;
6 6
 
7 7
 import com.reactnativenavigation.BaseTest;
8
-import com.reactnativenavigation.anim.ModalAnimator2;
8
+import com.reactnativenavigation.anim.ModalAnimator;
9 9
 import com.reactnativenavigation.mocks.SimpleViewController;
10 10
 import com.reactnativenavigation.parse.Options;
11 11
 import com.reactnativenavigation.utils.CommandListenerAdapter;
@@ -31,13 +31,13 @@ public class ModalStackTest2 extends BaseTest {
31 31
     private static final String MODAL_ID_2 = "modalId2";
32 32
     private static final String MODAL_ID_3 = "modalId3";
33 33
 
34
-    private ModalStack2 uut;
34
+    private ModalStack uut;
35 35
     private ViewController modal1;
36 36
     private ViewController modal2;
37 37
     private ViewController modal3;
38 38
     private Activity activity;
39 39
     private ModalPresenter presenter;
40
-    private ModalAnimator2 animator;
40
+    private ModalAnimator animator;
41 41
 
42 42
     @Override
43 43
     public void beforeEach() {
@@ -46,7 +46,7 @@ public class ModalStackTest2 extends BaseTest {
46 46
         activity.setContentView(root);
47 47
         animator = spy(new ModalAnimatorMock(activity));
48 48
         presenter = spy(new ModalPresenter(animator));
49
-        uut = new ModalStack2(presenter);
49
+        uut = new ModalStack(presenter);
50 50
         uut.setContentLayout(root);
51 51
         modal1 = spy(new SimpleViewController(activity, MODAL_ID_1, new Options()));
52 52
         modal2 = spy(new SimpleViewController(activity, MODAL_ID_2, new Options()));