소스 검색

Detach root by default when modal is displayed

Guy Carmeli 6 년 전
부모
커밋
66b5c4600a

+ 1
- 12
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/Navigator.java 파일 보기

@@ -172,18 +172,7 @@ public class Navigator extends ParentController {
172 172
     }
173 173
 
174 174
     public void showModal(final ViewController viewController, CommandListener listener) {
175
-        modalStack.showModal(viewController, new CommandListenerAdapter() {
176
-            @Override
177
-            public void onSuccess(String childId) {
178
-                contentLayout.removeView(root.getView());
179
-                listener.onSuccess(childId);
180
-            }
181
-
182
-            @Override
183
-            public void onError(String message) {
184
-                listener.onError(message);
185
-            }
186
-        });
175
+        modalStack.showModal(viewController, root, listener);
187 176
     }
188 177
 
189 178
     public void dismissModal(final String componentId, CommandListener listener) {

+ 6
- 5
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenter.java 파일 보기

@@ -3,6 +3,7 @@ package com.reactnativenavigation.viewcontrollers.modal;
3 3
 import android.animation.Animator;
4 4
 import android.animation.AnimatorListenerAdapter;
5 5
 import android.view.ViewGroup;
6
+import android.view.ViewManager;
6 7
 
7 8
 import com.reactnativenavigation.anim.ModalAnimator;
8 9
 import com.reactnativenavigation.viewcontrollers.Navigator.CommandListener;
@@ -23,22 +24,22 @@ public class ModalPresenter {
23 24
         this.content = contentLayout;
24 25
     }
25 26
 
26
-    public void showModal(ViewController toAdd, @Nullable ViewController toRemove, CommandListener listener) {
27
+    public void showModal(ViewController toAdd, ViewController toRemove, CommandListener listener) {
27 28
         content.addView(toAdd.getView());
28 29
         if (toAdd.options.animations.showModal.enable.isTrueOrUndefined()) {
29 30
             animator.show(toAdd.getView(), toAdd.options.animations.showModal, new AnimatorListenerAdapter() {
30 31
                 @Override
31 32
                 public void onAnimationEnd(Animator animation) {
32
-                    onShowModalEnd(toRemove, listener, toAdd);
33
+                    onShowModalEnd(toAdd, toRemove, listener);
33 34
                 }
34 35
             });
35 36
         } else {
36
-            onShowModalEnd(toRemove, listener, toAdd);
37
+            onShowModalEnd(toAdd, toRemove, listener);
37 38
         }
38 39
     }
39 40
 
40
-    private void onShowModalEnd(@Nullable ViewController toRemove, CommandListener listener, ViewController toAdd) {
41
-        if (toRemove != null) content.removeView(toRemove.getView());
41
+    private void onShowModalEnd(ViewController toAdd, ViewController toRemove, CommandListener listener) {
42
+        ((ViewManager) toRemove.getView().getParent()).removeView(toRemove.getView());
42 43
         listener.onSuccess(toAdd.getId());
43 44
     }
44 45
 

+ 2
- 2
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalStack.java 파일 보기

@@ -23,8 +23,8 @@ public class ModalStack {
23 23
         presenter.setContentLayout(contentLayout);
24 24
     }
25 25
 
26
-    public void showModal(ViewController viewController, CommandListener listener) {
27
-        ViewController toRemove = isEmpty() ? null : peek();
26
+    public void showModal(ViewController viewController, ViewController root, CommandListener listener) {
27
+        ViewController toRemove = isEmpty() ? root : peek();
28 28
         modals.add(viewController);
29 29
         presenter.showModal(viewController, toRemove, listener);
30 30
     }

+ 1
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/NavigatorTest.java 파일 보기

@@ -426,6 +426,7 @@ public class NavigatorTest extends BaseTest {
426 426
 
427 427
         uut.dismissModal(child1.getId(), new CommandListenerAdapter());
428 428
         assertThat(parentController.getView().getParent()).isNotNull();
429
+        verify(parentController, times(2)).onViewAppeared();
429 430
     }
430 431
 
431 432
     @Test

+ 19
- 8
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenterTest.java 파일 보기

@@ -1,6 +1,7 @@
1 1
 package com.reactnativenavigation.viewcontrollers.modal;
2 2
 
3 3
 import android.app.Activity;
4
+import android.view.ViewGroup;
4 5
 import android.widget.FrameLayout;
5 6
 
6 7
 import com.reactnativenavigation.BaseTest;
@@ -9,9 +10,11 @@ import com.reactnativenavigation.mocks.SimpleViewController;
9 10
 import com.reactnativenavigation.parse.Options;
10 11
 import com.reactnativenavigation.utils.CommandListenerAdapter;
11 12
 import com.reactnativenavigation.viewcontrollers.Navigator.CommandListener;
13
+import com.reactnativenavigation.viewcontrollers.ParentController;
12 14
 import com.reactnativenavigation.viewcontrollers.ViewController;
13 15
 
14 16
 import org.junit.Test;
17
+import org.mockito.Mockito;
15 18
 
16 19
 import static org.assertj.core.api.Java6Assertions.assertThat;
17 20
 import static org.mockito.ArgumentMatchers.any;
@@ -19,6 +22,7 @@ import static org.mockito.ArgumentMatchers.eq;
19 22
 import static org.mockito.Mockito.spy;
20 23
 import static org.mockito.Mockito.times;
21 24
 import static org.mockito.Mockito.verify;
25
+import static org.mockito.Mockito.when;
22 26
 
23 27
 public class ModalPresenterTest extends BaseTest {
24 28
     private static final String MODAL_ID_1 = "modalId1";
@@ -29,14 +33,21 @@ public class ModalPresenterTest extends BaseTest {
29 33
     private ModalPresenter uut;
30 34
     private FrameLayout contentLayout;
31 35
     private ModalAnimator animator;
36
+    private ViewController rootController;
32 37
 
33 38
     @Override
34 39
     public void beforeEach() {
35 40
         Activity activity = newActivity();
36
-        animator = spy(new ModalAnimator(activity));
37
-        uut = new ModalPresenter(animator);
41
+
42
+        ViewGroup root = new FrameLayout(activity);
43
+        rootController = Mockito.mock(ParentController.class);
44
+        when(this.rootController.getView()).then(invocation -> root);
38 45
         contentLayout = new FrameLayout(activity);
46
+        contentLayout.addView(root);
39 47
         activity.setContentView(contentLayout);
48
+
49
+        animator = spy(new ModalAnimator(activity));
50
+        uut = new ModalPresenter(animator);
40 51
         uut.setContentLayout(contentLayout);
41 52
         modal1 = spy(new SimpleViewController(activity, MODAL_ID_1, new Options()));
42 53
         modal2 = spy(new SimpleViewController(activity, MODAL_ID_2, new Options()));
@@ -52,7 +63,7 @@ public class ModalPresenterTest extends BaseTest {
52 63
                 verify(modal1, times(1)).onViewAppeared();
53 64
             }
54 65
         });
55
-        uut.showModal(modal1, null, listener);
66
+        uut.showModal(modal1, rootController, listener);
56 67
         verify(animator, times(0)).show(
57 68
                 eq(modal1.getView()),
58 69
                 eq(modal1.options.animations.showModal),
@@ -97,8 +108,8 @@ public class ModalPresenterTest extends BaseTest {
97 108
     public void dismissModal_animatesByDefault() {
98 109
         disableShowModalAnimation(modal1);
99 110
 
100
-        uut.showModal(modal1, null, new CommandListenerAdapter());
101
-        uut.dismissModal(modal1, null, new CommandListenerAdapter() {
111
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
112
+        uut.dismissModal(modal1, rootController, new CommandListenerAdapter() {
102 113
             @Override
103 114
             public void onSuccess(String childId) {
104 115
                 verify(modal1, times(1)).onViewDisappear();
@@ -122,8 +133,8 @@ public class ModalPresenterTest extends BaseTest {
122 133
         disableShowModalAnimation(modal1);
123 134
         disableDismissModalAnimation(modal1);
124 135
 
125
-        uut.showModal(modal1, null, new CommandListenerAdapter());
126
-        uut.dismissModal(modal1, null, new CommandListenerAdapter());
136
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
137
+        uut.dismissModal(modal1, rootController, new CommandListenerAdapter());
127 138
         verify(modal1, times(1)).onViewDisappear();
128 139
         verify(modal1, times(1)).destroy();
129 140
         verify(animator, times(0)).dismiss(any(), any());
@@ -133,7 +144,7 @@ public class ModalPresenterTest extends BaseTest {
133 144
     public void dismissModal_previousModalIsAddedBackToHierarchy() {
134 145
         disableShowModalAnimation(modal1, modal2);
135 146
 
136
-        uut.showModal(modal1, null, new CommandListenerAdapter());
147
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
137 148
         uut.showModal(modal2, modal1, new CommandListenerAdapter());
138 149
         assertThat(modal1.getView().getParent()).isNull();
139 150
         uut.dismissModal(modal2, modal1, new CommandListenerAdapter());

+ 34
- 21
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalStackTest.java 파일 보기

@@ -10,9 +10,11 @@ import com.reactnativenavigation.mocks.SimpleViewController;
10 10
 import com.reactnativenavigation.parse.Options;
11 11
 import com.reactnativenavigation.utils.CommandListenerAdapter;
12 12
 import com.reactnativenavigation.viewcontrollers.Navigator.CommandListener;
13
+import com.reactnativenavigation.viewcontrollers.ParentController;
13 14
 import com.reactnativenavigation.viewcontrollers.ViewController;
14 15
 
15 16
 import org.junit.Test;
17
+import org.mockito.Mockito;
16 18
 
17 19
 import java.util.EmptyStackException;
18 20
 
@@ -25,6 +27,7 @@ import static org.mockito.Mockito.spy;
25 27
 import static org.mockito.Mockito.times;
26 28
 import static org.mockito.Mockito.verify;
27 29
 import static org.mockito.Mockito.verifyZeroInteractions;
30
+import static org.mockito.Mockito.when;
28 31
 
29 32
 public class ModalStackTest extends BaseTest {
30 33
     private static final String MODAL_ID_1 = "modalId1";
@@ -38,16 +41,23 @@ public class ModalStackTest extends BaseTest {
38 41
     private Activity activity;
39 42
     private ModalPresenter presenter;
40 43
     private ModalAnimator animator;
44
+    private ViewController rootController;
41 45
 
42 46
     @Override
43 47
     public void beforeEach() {
44 48
         activity = newActivity();
49
+
45 50
         ViewGroup root = new FrameLayout(activity);
46
-        activity.setContentView(root);
51
+        rootController = Mockito.mock(ParentController.class);
52
+        when(this.rootController.getView()).then(invocation -> root);
53
+        FrameLayout activityContentView = new FrameLayout(activity);
54
+        activityContentView.addView(root);
55
+        activity.setContentView(activityContentView);
56
+
47 57
         animator = spy(new ModalAnimatorMock(activity));
48 58
         presenter = spy(new ModalPresenter(animator));
49 59
         uut = new ModalStack(presenter);
50
-        uut.setContentLayout(root);
60
+        uut.setContentLayout(activityContentView);
51 61
         modal1 = spy(new SimpleViewController(activity, MODAL_ID_1, new Options()));
52 62
         modal2 = spy(new SimpleViewController(activity, MODAL_ID_2, new Options()));
53 63
         modal3 = spy(new SimpleViewController(activity, MODAL_ID_3, new Options()));
@@ -57,7 +67,7 @@ public class ModalStackTest extends BaseTest {
57 67
     public void modalRefIsSaved() {
58 68
         disableShowModalAnimation(modal1);
59 69
         CommandListener listener = spy(new CommandListenerAdapter());
60
-        uut.showModal(modal1, listener);
70
+        uut.showModal(modal1, rootController, listener);
61 71
         verify(listener, times(1)).onSuccess(modal1.getId());
62 72
         assertThat(findModal(MODAL_ID_1)).isNotNull();
63 73
     }
@@ -65,17 +75,17 @@ public class ModalStackTest extends BaseTest {
65 75
     @Test
66 76
     public void showModal() {
67 77
         CommandListener listener = spy(new CommandListenerAdapter());
68
-        uut.showModal(modal1, listener);
78
+        uut.showModal(modal1, rootController, listener);
69 79
         verify(listener, times(1)).onSuccess(modal1.getId());
70 80
         assertThat(uut.size()).isOne();
71
-        verify(presenter, times(1)).showModal(modal1, null, listener);
81
+        verify(presenter, times(1)).showModal(modal1, rootController, listener);
72 82
         assertThat(findModal(MODAL_ID_1)).isNotNull();
73 83
     }
74 84
 
75 85
     @SuppressWarnings("Convert2Lambda")
76 86
     @Test
77 87
     public void dismissModal() {
78
-        uut.showModal(modal1, new CommandListenerAdapter());
88
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
79 89
         CommandListener listener = new CommandListenerAdapter();
80 90
         Runnable onModalWillDismiss = spy(new Runnable() {
81 91
             @Override
@@ -107,8 +117,8 @@ public class ModalStackTest extends BaseTest {
107 117
 
108 118
     @Test
109 119
     public void dismissAllModals() {
110
-        uut.showModal(modal1, new CommandListenerAdapter());
111
-        uut.showModal(modal2, new CommandListenerAdapter());
120
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
121
+        uut.showModal(modal2, rootController, new CommandListenerAdapter());
112 122
         CommandListener listener = spy(new CommandListenerAdapter() {
113 123
             @Override
114 124
             public void onSuccess(String childId) {
@@ -132,8 +142,8 @@ public class ModalStackTest extends BaseTest {
132 142
     @SuppressWarnings("Convert2Lambda")
133 143
     @Test
134 144
     public void dismissAllModals_onlyTopModalIsAnimated() {
135
-        uut.showModal(modal1, new CommandListenerAdapter());
136
-        uut.showModal(modal2, new CommandListenerAdapter());
145
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
146
+        uut.showModal(modal2, rootController, new CommandListenerAdapter());
137 147
 
138 148
         ViewGroup view1 = modal1.getView();
139 149
         ViewGroup view2 = modal2.getView();
@@ -154,8 +164,8 @@ public class ModalStackTest extends BaseTest {
154 164
 
155 165
     @Test
156 166
     public void dismissAllModals_bottomModalsAreDestroyed() {
157
-        uut.showModal(modal1, new CommandListenerAdapter());
158
-        uut.showModal(modal2, new CommandListenerAdapter());
167
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
168
+        uut.showModal(modal2, rootController, new CommandListenerAdapter());
159 169
 
160 170
         uut.dismissAllModals(new CommandListenerAdapter(), () -> {});
161 171
 
@@ -167,7 +177,7 @@ public class ModalStackTest extends BaseTest {
167 177
     @Test
168 178
     public void isEmpty() {
169 179
         assertThat(uut.isEmpty()).isTrue();
170
-        uut.showModal(modal1, new CommandListenerAdapter());
180
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
171 181
         assertThat(uut.isEmpty()).isFalse();
172 182
         uut.dismissAllModals(new CommandListenerAdapter(), () -> {});
173 183
         assertThat(uut.isEmpty()).isTrue();
@@ -177,7 +187,7 @@ public class ModalStackTest extends BaseTest {
177 187
     public void peek() {
178 188
         assertThat(uut.isEmpty()).isTrue();
179 189
         assertThatThrownBy(() -> uut.peek()).isInstanceOf(EmptyStackException.class);
180
-        uut.showModal(modal1, new CommandListenerAdapter() {
190
+        uut.showModal(modal1, rootController, new CommandListenerAdapter() {
181 191
             @Override
182 192
             public void onSuccess(String childId) {
183 193
                 assertThat(uut.peek()).isEqualTo(modal1);
@@ -189,8 +199,8 @@ public class ModalStackTest extends BaseTest {
189 199
     public void onDismiss_onViewAppearedInvokedOnPreviousModal() {
190 200
         disableShowModalAnimation(modal1, modal2);
191 201
 
192
-        uut.showModal(modal1, new CommandListenerAdapter());
193
-        uut.showModal(modal2, new CommandListenerAdapter());
202
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
203
+        uut.showModal(modal2, rootController, new CommandListenerAdapter());
194 204
         uut.dismissModal(modal2.getId(), () -> {}, new CommandListenerAdapter());
195 205
         verify(modal1, times(2)).onViewAppeared();
196 206
     }
@@ -200,9 +210,9 @@ public class ModalStackTest extends BaseTest {
200 210
         disableShowModalAnimation(modal1, modal2, modal3);
201 211
         disableDismissModalAnimation(modal1, modal2, modal3);
202 212
 
203
-        uut.showModal(modal1, new CommandListenerAdapter());
204
-        uut.showModal(modal2, new CommandListenerAdapter());
205
-        uut.showModal(modal3, new CommandListenerAdapter());
213
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
214
+        uut.showModal(modal2, rootController, new CommandListenerAdapter());
215
+        uut.showModal(modal3, rootController, new CommandListenerAdapter());
206 216
 
207 217
         uut.dismissModal(modal2.getId(), () -> {}, new CommandListenerAdapter());
208 218
         assertThat(uut.size()).isEqualTo(2);
@@ -220,7 +230,7 @@ public class ModalStackTest extends BaseTest {
220 230
     @Test
221 231
     public void handleBack_dismissModal() {
222 232
         disableDismissModalAnimation(modal1);
223
-        uut.showModal(modal1, new CommandListenerAdapter());
233
+        uut.showModal(modal1, rootController, new CommandListenerAdapter());
224 234
         assertThat(uut.handleBack(new CommandListenerAdapter(), () -> {})).isTrue();
225 235
         verify(modal1, times(1)).onViewDisappear();
226 236
 
@@ -234,7 +244,10 @@ public class ModalStackTest extends BaseTest {
234 244
                 return true;
235 245
             }
236 246
         });
237
-        uut.showModal(backHandlingModal, new CommandListenerAdapter());
247
+        uut.showModal(backHandlingModal, rootController, new CommandListenerAdapter());
248
+
249
+        rootController.getView().getViewTreeObserver().dispatchOnGlobalLayout();
250
+
238 251
         assertThat(uut.handleBack(new CommandListenerAdapter(), any())).isTrue();
239 252
         verify(backHandlingModal, times(1)).handleBack(any());
240 253
         verify(backHandlingModal, times(0)).onViewDisappear();