Browse Source

Merge Stack child options only for current child of stack

Currently child options are applied only for visible children. During push animations, both children are visible.
If mergeOptions is called on the disappearing child during push animation, wrong options will be applied.

This commit changes the conditional so that child options are merged to stack if the child is also the current child.
Guy Carmeli 6 years ago
parent
commit
d43a3bdcaa

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

@@ -392,6 +392,7 @@ public class StackPresenter {
392 392
         if (options.subtitle.fontFamily != null) topBar.setSubtitleFontFamily(options.subtitle.fontFamily);
393 393
 
394 394
         if (options.background.color.hasValue()) topBar.setBackgroundColor(options.background.color.get());
395
+        if (options.background.component.hasValue()) topBar.setBackgroundComponent(options.background.component);
395 396
 
396 397
         if (options.testId.hasValue()) topBar.setTestId(options.testId.get());
397 398
 

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

@@ -104,7 +104,7 @@ public class StackController extends ParentController<StackLayout> {
104 104
     @Override
105 105
     public void mergeChildOptions(Options options, ViewController childController, Component child) {
106 106
         super.mergeChildOptions(options, childController, child);
107
-        if (childController.isViewShown()) {
107
+        if (childController.isViewShown() && peek() == childController) {
108 108
             presenter.mergeChildOptions(options, resolveCurrentOptions(), child);
109 109
             if (options.fabOptions.hasValue() && child instanceof ReactComponent) {
110 110
                 fabOptionsPresenter.mergeOptions(options.fabOptions, (ReactComponent) child, getView());

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

@@ -92,7 +92,9 @@ public class ComponentLayout extends FrameLayout implements ReactComponent, Titl
92 92
         if (getLayoutParams() instanceof RelativeLayout.LayoutParams) {
93 93
             RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
94 94
             layoutParams.topMargin = ViewUtils.getHeight(topBar);
95
-            setLayoutParams(layoutParams);
95
+            try {
96
+                setLayoutParams(layoutParams);
97
+            } catch (IllegalStateException ignored) { }
96 98
         }
97 99
     }
98 100
 

+ 38
- 67
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/OptionsApplyingTest.java View File

@@ -14,10 +14,7 @@ import com.reactnativenavigation.mocks.TestReactView;
14 14
 import com.reactnativenavigation.mocks.TitleBarReactViewCreatorMock;
15 15
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
16 16
 import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
17
-import com.reactnativenavigation.mocks.TypefaceLoaderMock;
18 17
 import com.reactnativenavigation.parse.Options;
19
-import com.reactnativenavigation.parse.SubtitleOptions;
20
-import com.reactnativenavigation.parse.TopBarBackgroundOptions;
21 18
 import com.reactnativenavigation.parse.params.Bool;
22 19
 import com.reactnativenavigation.parse.params.Colour;
23 20
 import com.reactnativenavigation.parse.params.Fraction;
@@ -33,7 +30,6 @@ import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
33 30
 import com.reactnativenavigation.views.StackLayout;
34 31
 import com.reactnativenavigation.views.topbar.TopBar;
35 32
 
36
-import org.json.JSONObject;
37 33
 import org.junit.Test;
38 34
 
39 35
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
@@ -46,7 +42,7 @@ import static org.mockito.Mockito.verify;
46 42
 
47 43
 public class OptionsApplyingTest extends BaseTest {
48 44
     private Activity activity;
49
-    private StackController stackController;
45
+    private StackController stack;
50 46
     private ComponentViewController uut;
51 47
     private IReactView view;
52 48
     private Options initialNavigationOptions;
@@ -79,13 +75,14 @@ public class OptionsApplyingTest extends BaseTest {
79 75
                 return topBar;
80 76
             }
81 77
         };
82
-        stackController = TestUtils.newStackController(activity)
78
+        stack = TestUtils.newStackController(activity)
83 79
                 .setTopBarController(topBarController)
84 80
                 .build();
85
-        stackController.ensureViewIsCreated();
86
-        stackController.getView().layout(0, 0, 1000, 1000);
87
-        stackController.getTopBar().layout(0, 0, 1000, 100);
88
-        uut.setParentController(stackController);
81
+        stack.ensureViewIsCreated();
82
+        stack.getView().layout(0, 0, 1000, 1000);
83
+        stack.getTopBar().layout(0, 0, 1000, 100);
84
+        activity.setContentView(stack.getView());
85
+        disablePushAnimation(uut);
89 86
     }
90 87
 
91 88
     @SuppressWarnings("ConstantConditions")
@@ -120,7 +117,6 @@ public class OptionsApplyingTest extends BaseTest {
120 117
 
121 118
     @Test
122 119
     public void mergeNavigationOptionsUpdatesCurrentOptions() {
123
-        uut.ensureViewIsCreated();
124 120
         assertThat(uut.options.topBar.title.text.get("")).isEmpty();
125 121
         Options options = new Options();
126 122
         options.topBar.title.text = new Text("new title");
@@ -130,44 +126,32 @@ public class OptionsApplyingTest extends BaseTest {
130 126
 
131 127
     @Test
132 128
     public void reappliesOptionsOnMerge() {
133
-        uut.ensureViewIsCreated();
134
-        uut.onViewAppeared();
135
-        assertThat(stackController.getTopBar().getTitle()).isEmpty();
129
+        assertThat(stack.getTopBar().getTitle()).isEmpty();
130
+        stack.push(uut, new CommandListenerAdapter());
136 131
 
137 132
         Options opts = new Options();
138 133
         opts.topBar.title.text = new Text("the new title");
139 134
         uut.mergeOptions(opts);
140 135
 
141
-        assertThat(stackController.getTopBar().getTitle()).isEqualTo("the new title");
136
+        assertThat(stack.getTopBar().getTitle()).isEqualTo("the new title");
142 137
     }
143 138
 
144 139
     @Test
145 140
     public void appliesTopBackBackgroundColor() {
146
-        uut.ensureViewIsCreated();
147
-        uut.onViewAppeared();
148
-
149
-        Options opts = new Options();
150
-        opts.topBar.background.color = new Colour(Color.RED);
151
-        uut.mergeOptions(opts);
152
-
153
-        assertThat(((ColorDrawable) stackController.getTopBar().getBackground()).getColor()).isEqualTo(Color.RED);
141
+        uut.options.topBar.background.color = new Colour(Color.RED);
142
+        stack.push(uut, new CommandListenerAdapter());
143
+        assertThat(((ColorDrawable) stack.getTopBar().getBackground()).getColor()).isEqualTo(Color.RED);
154 144
     }
155 145
 
156 146
     @Test
157 147
     public void appliesTopBarTextColor() {
158 148
         assertThat(uut.initialOptions).isSameAs(initialNavigationOptions);
159
-        stackController.push(uut, new CommandListenerAdapter() {
160
-            @Override
161
-            public void onSuccess(String childId) {
162
-                Options opts = new Options();
163
-                opts.topBar.title.text = new Text("the title");
164
-                opts.topBar.title.color = new Colour(Color.RED);
165
-                uut.mergeOptions(opts);
149
+        uut.options.topBar.title.text = new Text("the title");
150
+        uut.options.topBar.title.color = new Colour(Color.RED);
151
+        stack.push(uut, new CommandListenerAdapter());
166 152
 
167
-                assertThat(stackController.getTopBar().getTitleTextView()).isNotEqualTo(null);
168
-                assertThat(stackController.getTopBar().getTitleTextView().getCurrentTextColor()).isEqualTo(Color.RED);
169
-            }
170
-        });
153
+        assertThat(stack.getTopBar().getTitleTextView()).isNotEqualTo(null);
154
+        assertThat(stack.getTopBar().getTitleTextView().getCurrentTextColor()).isEqualTo(Color.RED);
171 155
     }
172 156
 
173 157
     @SuppressWarnings("MagicNumber")
@@ -175,32 +159,29 @@ public class OptionsApplyingTest extends BaseTest {
175 159
     public void appliesTopBarTextSize() {
176 160
         assertThat(uut.initialOptions).isSameAs(initialNavigationOptions);
177 161
         initialNavigationOptions.topBar.title.text = new Text("the title");
178
-        uut.ensureViewIsCreated();
179
-        uut.onViewAppeared();
180 162
 
181
-        Options opts = new Options();
182
-        opts.topBar.title.text = new Text("the title");
183
-        opts.topBar.title.fontSize = new Fraction(18);
184
-        uut.mergeOptions(opts);
163
+        uut.options.topBar.title.text = new Text("the title");
164
+        uut.options.topBar.title.fontSize = new Fraction(18);
165
+        stack.push(uut, new CommandListenerAdapter());
185 166
 
186
-        assertThat(stackController.getTopBar().getTitleTextView()).isNotEqualTo(null);
187
-        assertThat(stackController.getTopBar().getTitleTextView().getTextSize()).isEqualTo(18);
167
+        assertThat(stack.getTopBar().getTitleTextView()).isNotEqualTo(null);
168
+        assertThat(stack.getTopBar().getTitleTextView().getTextSize()).isEqualTo(18);
188 169
     }
189 170
 
190 171
     @Test
191 172
     public void appliesTopBarVisible() {
173
+        stack.push(uut, new CommandListenerAdapter());
174
+
192 175
         assertThat(uut.initialOptions).isSameAs(initialNavigationOptions);
193 176
         initialNavigationOptions.topBar.title.text = new Text("the title");
194
-        uut.ensureViewIsCreated();
195
-        uut.onViewAppeared();
196
-        assertThat(stackController.getTopBar().getVisibility()).isNotEqualTo(View.GONE);
177
+        assertThat(stack.getTopBar().getVisibility()).isNotEqualTo(View.GONE);
197 178
 
198 179
         Options opts = new Options();
199 180
         opts.topBar.visible = new Bool(false);
200 181
         opts.topBar.animate = new Bool(false);
201 182
         uut.mergeOptions(opts);
202 183
 
203
-        assertThat(stackController.getTopBar().getVisibility()).isEqualTo(View.GONE);
184
+        assertThat(stack.getTopBar().getVisibility()).isEqualTo(View.GONE);
204 185
     }
205 186
 
206 187
     @Test
@@ -208,8 +189,8 @@ public class OptionsApplyingTest extends BaseTest {
208 189
         uut.options.topBar.title.text = new Text("the title");
209 190
         uut.options.topBar.drawBehind = new Bool(false);
210 191
         uut.ensureViewIsCreated();
211
-        stackController.ensureViewIsCreated();
212
-        stackController.push(uut, new CommandListenerAdapter() {
192
+        stack.ensureViewIsCreated();
193
+        stack.push(uut, new CommandListenerAdapter() {
213 194
             @Override
214 195
             public void onSuccess(String childId) {
215 196
                 uut.onViewAppeared();
@@ -221,33 +202,23 @@ public class OptionsApplyingTest extends BaseTest {
221 202
                 uut.mergeOptions(opts);
222 203
 
223 204
                 uutLayoutParams = (RelativeLayout.LayoutParams) (uut.getComponent().asView()).getLayoutParams();
224
-                assertThat(uutLayoutParams.getRule(BELOW)).isNotEqualTo(stackController.getTopBar().getId());
205
+                assertThat(uutLayoutParams.getRule(BELOW)).isNotEqualTo(stack.getTopBar().getId());
225 206
             }
226 207
         });
227 208
     }
228 209
 
229 210
     @Test
230
-    public void appliesTopBarComponent() throws Exception {
231
-        disablePushAnimation(uut);
232
-        JSONObject json = new JSONObject();
233
-        json.put("component", new JSONObject().put("name","someComponent").put("componentId", "id"));
234
-        uut.options.topBar.background = TopBarBackgroundOptions.parse(json);
235
-        uut.ensureViewIsCreated();
236
-        stackController.push(uut, new CommandListenerAdapter());
237
-        uut.onViewAppeared();
238
-
211
+    public void appliesTopBarComponent() {
212
+        uut.options.topBar.background.component.name = new Text("someComponent");
213
+        uut.options.topBar.background.component.componentId = new Text("id");
214
+        stack.push(uut, new CommandListenerAdapter());
239 215
         verify(topBar, times(1)).setBackgroundComponent(any());
240 216
     }
241 217
 
242 218
     @Test
243
-    public void appliesSubtitle() throws Exception {
244
-        JSONObject json = new JSONObject();
245
-        json.put("text", "sub");
246
-        uut.options.topBar.subtitle = SubtitleOptions.parse(new TypefaceLoaderMock(), json);
247
-        uut.ensureViewIsCreated();
248
-        stackController.push(uut, new CommandListenerAdapter());
249
-        uut.onViewAppeared();
250
-
251
-        assertThat(stackController.getTopBar().getTitleBar().getSubtitle()).isEqualTo("sub");
219
+    public void appliesSubtitle() {
220
+        uut.options.topBar.subtitle.text = new Text("sub");
221
+        stack.push(uut, new CommandListenerAdapter());
222
+        assertThat(stack.getTopBar().getTitleBar().getSubtitle()).isEqualTo("sub");
252 223
     }
253 224
 }

+ 9
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/stack/StackControllerTest.java View File

@@ -916,6 +916,15 @@ public class StackControllerTest extends BaseTest {
916 916
         verify(presenter, times(0)).mergeChildOptions(any(), any(), any());
917 917
     }
918 918
 
919
+    @Test
920
+    public void mergeChildOptions_presenterMergesOptionsOnlyForCurrentChild() {
921
+        ViewController vc = mock(ViewController.class);
922
+        when(vc.isViewShown()).thenReturn(true);
923
+        Component child = mock(Component.class);
924
+        uut.mergeChildOptions(new Options(), vc, child);
925
+        verify(presenter, times(0)).mergeChildOptions(any(), any(), any());
926
+    }
927
+
919 928
     @Test
920 929
     public void resolvedOptionsAreAppliedWhenStackIsAttachedToParentAndNotVisible() {
921 930
         FrameLayout parent = new FrameLayout(activity);