ソースを参照

Add previous controller to screen only when dismissing top modal

Guy Carmeli 6 年 前
コミット
4202f8643d

+ 6
- 1
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenter.java ファイルの表示

@@ -2,6 +2,7 @@ package com.reactnativenavigation.viewcontrollers.modal;
2 2
 
3 3
 import android.animation.Animator;
4 4
 import android.animation.AnimatorListenerAdapter;
5
+import android.support.annotation.NonNull;
5 6
 import android.view.ViewGroup;
6 7
 
7 8
 import com.reactnativenavigation.anim.ModalAnimator;
@@ -43,8 +44,12 @@ public class ModalPresenter {
43 44
         listener.onSuccess(toAdd.getId());
44 45
     }
45 46
 
46
-    public void dismissModal(ViewController toDismiss, ViewController toAdd, CommandListener listener) {
47
+    public void dismissTopModal(ViewController toDismiss, @NonNull ViewController toAdd, CommandListener listener) {
47 48
         toAdd.attachView(content, 0);
49
+        dismissModal(toDismiss, listener);
50
+    }
51
+
52
+    public void dismissModal(ViewController toDismiss, CommandListener listener) {
48 53
         if (toDismiss.options.animations.dismissModal.enable.isTrueOrUndefined()) {
49 54
             animator.dismiss(toDismiss.getView(), new AnimatorListenerAdapter() {
50 55
                 @Override

+ 8
- 3
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalStack.java ファイルの表示

@@ -32,9 +32,14 @@ public class ModalStack {
32 32
     public void dismissModal(String componentId, ViewController root, CommandListener listener) {
33 33
         ViewController toDismiss = findModalByComponentId(componentId);
34 34
         if (toDismiss != null) {
35
-            ViewController toAdd = isTop(toDismiss) ? get(size() - 2) : root;
35
+            boolean isTop = isTop(toDismiss);
36 36
             modals.remove(toDismiss);
37
-            presenter.dismissModal(toDismiss, toAdd, listener);
37
+            ViewController toAdd = isEmpty() ? root : isTop ? get(size() - 1) : null;
38
+            if (isTop) {
39
+                presenter.dismissTopModal(toDismiss, toAdd, listener);
40
+            } else {
41
+                presenter.dismissModal(toDismiss, listener);
42
+            }
38 43
         } else {
39 44
             listener.onError("Nothing to dismiss");
40 45
         }
@@ -83,7 +88,7 @@ public class ModalStack {
83 88
     }
84 89
 
85 90
     private boolean isTop(ViewController modal) {
86
-        return size() > 1 && peek().equals(modal);
91
+        return !isEmpty() && peek().equals(modal);
87 92
     }
88 93
 
89 94
     @Nullable

+ 24
- 25
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenterTest.java ファイルの表示

@@ -1,7 +1,6 @@
1 1
 package com.reactnativenavigation.viewcontrollers.modal;
2 2
 
3 3
 import android.app.Activity;
4
-import android.view.ViewGroup;
5 4
 import android.widget.FrameLayout;
6 5
 
7 6
 import com.reactnativenavigation.BaseTest;
@@ -13,11 +12,9 @@ import com.reactnativenavigation.utils.CommandListener;
13 12
 import com.reactnativenavigation.utils.CommandListenerAdapter;
14 13
 import com.reactnativenavigation.viewcontrollers.ChildController;
15 14
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
16
-import com.reactnativenavigation.viewcontrollers.ParentController;
17 15
 import com.reactnativenavigation.viewcontrollers.ViewController;
18 16
 
19 17
 import org.junit.Test;
20
-import org.mockito.Mockito;
21 18
 
22 19
 import static org.assertj.core.api.Java6Assertions.assertThat;
23 20
 import static org.mockito.ArgumentMatchers.any;
@@ -25,7 +22,6 @@ import static org.mockito.ArgumentMatchers.eq;
25 22
 import static org.mockito.Mockito.spy;
26 23
 import static org.mockito.Mockito.times;
27 24
 import static org.mockito.Mockito.verify;
28
-import static org.mockito.Mockito.when;
29 25
 
30 26
 public class ModalPresenterTest extends BaseTest {
31 27
     private static final String MODAL_ID_1 = "modalId1";
@@ -37,18 +33,15 @@ public class ModalPresenterTest extends BaseTest {
37 33
     private FrameLayout contentLayout;
38 34
     private ModalAnimator animator;
39 35
     private ViewController rootController;
40
-    private ChildControllersRegistry childRegistry;
41 36
 
42 37
     @Override
43 38
     public void beforeEach() {
44 39
         Activity activity = newActivity();
45
-        childRegistry = new ChildControllersRegistry();
40
+        ChildControllersRegistry childRegistry = new ChildControllersRegistry();
46 41
 
47
-        ViewGroup root = new FrameLayout(activity);
48
-        rootController = Mockito.mock(ParentController.class);
49
-        when(this.rootController.getView()).then(invocation -> root);
42
+        rootController = spy(new SimpleViewController(activity, childRegistry, "root", new Options()));
50 43
         contentLayout = new FrameLayout(activity);
51
-        contentLayout.addView(root);
44
+        contentLayout.addView(rootController.getView());
52 45
         activity.setContentView(contentLayout);
53 46
 
54 47
         animator = spy(new ModalAnimator(activity));
@@ -114,7 +107,7 @@ public class ModalPresenterTest extends BaseTest {
114 107
         disableShowModalAnimation(modal1);
115 108
 
116 109
         uut.showModal(modal1, rootController, new CommandListenerAdapter());
117
-        uut.dismissModal(modal1, rootController, new CommandListenerAdapter() {
110
+        uut.dismissTopModal(modal1, rootController, new CommandListenerAdapter() {
118 111
             @Override
119 112
             public void onSuccess(String childId) {
120 113
                 verify(modal1, times(1)).onViewDisappear();
@@ -130,28 +123,17 @@ public class ModalPresenterTest extends BaseTest {
130 123
         modal2.ensureViewIsCreated();
131 124
         FrameLayout spy = spy(new FrameLayout(newActivity()));
132 125
         uut.setContentLayout(spy);
133
-        uut.dismissModal(modal1, modal2, new CommandListenerAdapter());
126
+        uut.dismissTopModal(modal1, modal2, new CommandListenerAdapter());
134 127
         verify(spy, times(1)).addView(modal2.getView(), 0);
135 128
     }
136 129
 
137
-    @Test
138
-    public void dismissModal_onViewBroughtToFront_invokedOnPreviousView() {
139
-        disableShowModalAnimation(modal1, modal2);
140
-        disableDismissModalAnimation(modal1, modal2);
141
-
142
-        uut.showModal(modal1, rootController, new CommandListenerAdapter());
143
-        uut.showModal(modal2, rootController, new CommandListenerAdapter());
144
-        uut.dismissModal(modal2, modal1, new CommandListenerAdapter());
145
-        verify(modal1, times(1)).onViewBroughtToFront();
146
-    }
147
-
148 130
     @Test
149 131
     public void dismissModal_noAnimation() {
150 132
         disableShowModalAnimation(modal1);
151 133
         disableDismissModalAnimation(modal1);
152 134
 
153 135
         uut.showModal(modal1, rootController, new CommandListenerAdapter());
154
-        uut.dismissModal(modal1, rootController, new CommandListenerAdapter());
136
+        uut.dismissTopModal(modal1, rootController, new CommandListenerAdapter());
155 137
         verify(modal1, times(1)).onViewDisappear();
156 138
         verify(modal1, times(1)).destroy();
157 139
         verify(animator, times(0)).dismiss(any(), any());
@@ -164,10 +146,27 @@ public class ModalPresenterTest extends BaseTest {
164 146
         uut.showModal(modal1, rootController, new CommandListenerAdapter());
165 147
         uut.showModal(modal2, modal1, new CommandListenerAdapter());
166 148
         assertThat(modal1.getView().getParent()).isNull();
167
-        uut.dismissModal(modal2, modal1, new CommandListenerAdapter());
149
+        uut.dismissTopModal(modal2, modal1, new CommandListenerAdapter());
168 150
         verify(modal1, times(2)).onViewAppeared();
169 151
     }
170 152
 
153
+    @Test
154
+    public void dismissModal_previousControllerIsNotAddedIfDismissedModalIsNotTop() {
155
+        disableShowModalAnimation(modal1, modal2);
156
+        disableDismissModalAnimation(modal1, modal2);
157
+
158
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
159
+        uut.showModal(modal2, modal1, new CommandListenerAdapter());
160
+        assertThat(modal1.getView().getParent()).isNull();
161
+        assertThat(rootController.getView().getParent()).isNull();
162
+
163
+        uut.dismissModal(modal1, new CommandListenerAdapter());
164
+        assertThat(rootController.getView().getParent()).isNull();
165
+
166
+        uut.dismissTopModal(modal2, rootController, new CommandListenerAdapter());
167
+        assertThat(rootController.getView().getParent()).isNotNull();
168
+    }
169
+
171 170
     @Test
172 171
     public void dismissModal_previousViewIsNotDetachedIfOverCurrentContext() {
173 172
         modal1.options.modal.presentationStyle = ModalPresentationStyle.OverCurrentContext;

+ 23
- 9
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalStackTest.java ファイルの表示

@@ -11,11 +11,9 @@ import com.reactnativenavigation.parse.Options;
11 11
 import com.reactnativenavigation.utils.CommandListener;
12 12
 import com.reactnativenavigation.utils.CommandListenerAdapter;
13 13
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
14
-import com.reactnativenavigation.viewcontrollers.ParentController;
15 14
 import com.reactnativenavigation.viewcontrollers.ViewController;
16 15
 
17 16
 import org.junit.Test;
18
-import org.mockito.Mockito;
19 17
 
20 18
 import java.util.EmptyStackException;
21 19
 
@@ -28,7 +26,6 @@ import static org.mockito.Mockito.spy;
28 26
 import static org.mockito.Mockito.times;
29 27
 import static org.mockito.Mockito.verify;
30 28
 import static org.mockito.Mockito.verifyZeroInteractions;
31
-import static org.mockito.Mockito.when;
32 29
 
33 30
 public class ModalStackTest extends BaseTest {
34 31
     private static final String MODAL_ID_1 = "modalId1";
@@ -50,11 +47,9 @@ public class ModalStackTest extends BaseTest {
50 47
         activity = newActivity();
51 48
         childRegistry = new ChildControllersRegistry();
52 49
 
53
-        ViewGroup root = new FrameLayout(activity);
54
-        rootController = Mockito.mock(ParentController.class);
55
-        when(this.rootController.getView()).then(invocation -> root);
50
+        this.rootController = new SimpleViewController(activity, childRegistry, "root", new Options());
56 51
         FrameLayout activityContentView = new FrameLayout(activity);
57
-        activityContentView.addView(root);
52
+        activityContentView.addView(rootController.getView());
58 53
         activity.setContentView(activityContentView);
59 54
 
60 55
         animator = spy(new ModalAnimatorMock(activity));
@@ -92,7 +87,7 @@ public class ModalStackTest extends BaseTest {
92 87
         CommandListener listener = new CommandListenerAdapter();
93 88
         uut.dismissModal(modal1.getId(), rootController, listener);
94 89
         assertThat(findModal(modal1.getId())).isNull();
95
-        verify(presenter, times(1)).dismissModal(modal1, rootController, listener);
90
+        verify(presenter, times(1)).dismissTopModal(modal1, rootController, listener);
96 91
     }
97 92
 
98 93
     @SuppressWarnings("Convert2Lambda")
@@ -111,6 +106,25 @@ public class ModalStackTest extends BaseTest {
111 106
         verifyZeroInteractions(listener);
112 107
     }
113 108
 
109
+    @Test
110
+    public void dismissModal_dismissDeepModal() {
111
+        disableShowModalAnimation(modal1, modal2, modal3);
112
+        disableDismissModalAnimation(modal1, modal2, modal3);
113
+
114
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
115
+        uut.showModal(modal2, rootController, new CommandListenerAdapter());
116
+        uut.showModal(modal3, rootController, new CommandListenerAdapter());
117
+
118
+        assertThat(rootController.getView().getParent()).isNull();
119
+        uut.dismissModal(modal1.getId(), rootController, new CommandListenerAdapter());
120
+        assertThat(rootController.getView().getParent()).isNull();
121
+
122
+        uut.dismissModal(modal3.getId(), rootController, new CommandListenerAdapter());
123
+        uut.dismissModal(modal2.getId(), rootController, new CommandListenerAdapter());
124
+        assertThat(rootController.getView().getParent()).isNotNull();
125
+        assertThat(rootController.getView().isShown()).isTrue();
126
+    }
127
+
114 128
     @Test
115 129
     public void dismissAllModals() {
116 130
         uut.showModal(modal1, rootController, new CommandListenerAdapter());
@@ -145,7 +159,7 @@ public class ModalStackTest extends BaseTest {
145 159
         ViewGroup view2 = modal2.getView();
146 160
         CommandListener listener = spy(new CommandListenerAdapter());
147 161
         uut.dismissAllModals(listener, rootController);
148
-        verify(presenter, times(1)).dismissModal(modal2, rootController, listener);
162
+        verify(presenter, times(1)).dismissTopModal(modal2, rootController, listener);
149 163
         verify(animator, times(0)).dismiss(eq(view1), any());
150 164
         verify(animator, times(1)).dismiss(eq(view2), any());
151 165
         assertThat(uut.size()).isEqualTo(0);