Daniel Zlotin 7 年前
父节点
当前提交
38e85f8a69

+ 14
- 16
lib/android/app/src/main/java/com/reactnativenavigation/anim/BaseAnimator.java 查看文件

3
 
3
 
4
 import android.animation.AnimatorSet;
4
 import android.animation.AnimatorSet;
5
 import android.animation.ObjectAnimator;
5
 import android.animation.ObjectAnimator;
6
+import android.animation.TimeInterpolator;
6
 import android.content.Context;
7
 import android.content.Context;
7
 import android.support.annotation.NonNull;
8
 import android.support.annotation.NonNull;
8
 import android.view.View;
9
 import android.view.View;
9
-import android.view.animation.AccelerateInterpolator;
10
+import android.view.animation.AccelerateDecelerateInterpolator;
10
 import android.view.animation.DecelerateInterpolator;
11
 import android.view.animation.DecelerateInterpolator;
11
 
12
 
12
 import com.reactnativenavigation.parse.AnimationsOptions;
13
 import com.reactnativenavigation.parse.AnimationsOptions;
13
 import com.reactnativenavigation.utils.UiUtils;
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
 class BaseAnimator {
19
 class BaseAnimator {
16
 
20
 
17
     private static final int DURATION = 300;
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
     protected AnimationsOptions options = new AnimationsOptions();
25
     protected AnimationsOptions options = new AnimationsOptions();
22
 
26
 
28
 
32
 
29
     @NonNull
33
     @NonNull
30
     AnimatorSet getDefaultPushAnimation(View view) {
34
     AnimatorSet getDefaultPushAnimation(View view) {
31
-        ObjectAnimator alpha = ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1);
32
-        alpha.setInterpolator(DECELERATE_INTERPOLATOR);
33
-
34
         AnimatorSet set = new AnimatorSet();
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
         set.setDuration(DURATION);
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
         set.playTogether(translationY, alpha);
40
         set.playTogether(translationY, alpha);
39
         return set;
41
         return set;
40
     }
42
     }
43
     @NonNull
45
     @NonNull
44
     AnimatorSet getDefaultPopAnimation(View view) {
46
     AnimatorSet getDefaultPopAnimation(View view) {
45
         AnimatorSet set = new AnimatorSet();
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
         set.playTogether(translationY, alpha);
52
         set.playTogether(translationY, alpha);
55
         return set;
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 查看文件

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

+ 13
- 9
lib/android/app/src/main/java/com/reactnativenavigation/anim/TopBarAnimator.java 查看文件

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

+ 6
- 17
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/Navigator.java 查看文件

9
 import android.widget.FrameLayout;
9
 import android.widget.FrameLayout;
10
 
10
 
11
 import com.facebook.react.bridge.Promise;
11
 import com.facebook.react.bridge.Promise;
12
-import com.reactnativenavigation.anim.ModalAnimator2;
12
+import com.reactnativenavigation.anim.ModalAnimator;
13
 import com.reactnativenavigation.anim.NavigationAnimator;
13
 import com.reactnativenavigation.anim.NavigationAnimator;
14
 import com.reactnativenavigation.parse.Options;
14
 import com.reactnativenavigation.parse.Options;
15
 import com.reactnativenavigation.presentation.NavigationOptionsListener;
15
 import com.reactnativenavigation.presentation.NavigationOptionsListener;
17
 import com.reactnativenavigation.utils.CommandListenerAdapter;
17
 import com.reactnativenavigation.utils.CommandListenerAdapter;
18
 import com.reactnativenavigation.utils.CompatUtils;
18
 import com.reactnativenavigation.utils.CompatUtils;
19
 import com.reactnativenavigation.viewcontrollers.modal.ModalPresenter;
19
 import com.reactnativenavigation.viewcontrollers.modal.ModalPresenter;
20
-import com.reactnativenavigation.viewcontrollers.modal.ModalStack2;
20
+import com.reactnativenavigation.viewcontrollers.modal.ModalStack;
21
 
21
 
22
 import java.util.Collection;
22
 import java.util.Collection;
23
 import java.util.Collections;
23
 import java.util.Collections;
30
         void onError(String message);
30
         void onError(String message);
31
     }
31
     }
32
 
32
 
33
-    private final ModalStack2 modalStack;
33
+    private final ModalStack modalStack;
34
     private ViewController root;
34
     private ViewController root;
35
     private FrameLayout rootLayout;
35
     private FrameLayout rootLayout;
36
     private FrameLayout contentLayout;
36
     private FrameLayout contentLayout;
39
 
39
 
40
     public Navigator(final Activity activity) {
40
     public Navigator(final Activity activity) {
41
         super(activity, "navigator" + CompatUtils.generateViewId(), new Options());
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
     public FrameLayout getContentLayout() {
45
     public FrameLayout getContentLayout() {
87
         }
87
         }
88
 
88
 
89
         root = viewController;
89
         root = viewController;
90
-
91
         contentLayout.addView(viewController.getView());
90
         contentLayout.addView(viewController.getView());
92
         if (viewController.options.animations.startApp.hasValue()) {
91
         if (viewController.options.animations.startApp.hasValue()) {
93
             new NavigationAnimator(viewController.getActivity(), viewController.options.animations)
92
             new NavigationAnimator(viewController.getActivity(), viewController.options.animations)
184
     }
183
     }
185
 
184
 
186
     public void dismissModal(final String componentId, CommandListener listener) {
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
     public void dismissAllModals(CommandListener listener) {
190
     public void dismissAllModals(CommandListener listener) {

+ 3
- 3
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenter.java 查看文件

4
 import android.animation.AnimatorListenerAdapter;
4
 import android.animation.AnimatorListenerAdapter;
5
 import android.view.ViewGroup;
5
 import android.view.ViewGroup;
6
 
6
 
7
-import com.reactnativenavigation.anim.ModalAnimator2;
7
+import com.reactnativenavigation.anim.ModalAnimator;
8
 import com.reactnativenavigation.viewcontrollers.Navigator.CommandListener;
8
 import com.reactnativenavigation.viewcontrollers.Navigator.CommandListener;
9
 import com.reactnativenavigation.viewcontrollers.ViewController;
9
 import com.reactnativenavigation.viewcontrollers.ViewController;
10
 
10
 
13
 public class ModalPresenter {
13
 public class ModalPresenter {
14
 
14
 
15
     private ViewGroup content;
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
         this.animator = animator;
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 查看文件

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

+ 16
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/NavigatorTest.java 查看文件

412
         verify(parentController, times(2)).onViewAppeared();
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
     @Test
431
     @Test
416
     public void dismissAllModals_onViewAppearedInvokedOnRoot() {
432
     public void dismissAllModals_onViewAppearedInvokedOnRoot() {
417
         disableShowModalAnimation(child1);
433
         disableShowModalAnimation(child1);

+ 2
- 2
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalAnimatorMock.java 查看文件

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

+ 3
- 3
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenterTest.java 查看文件

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

+ 4
- 4
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalStackTest2.java 查看文件

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