ソースを参照

Merge options into popped screen correctly

Options were merged after screen was popped from the backing stack data structure.
This meant that options were not resolved correctly for it as it was already detached from the stack.
This was especially noticeable when declaring a custom animation is mergeOptions passed to Navigation.pop().

Fixes #3869 and closes #4138
Guy Carmeli 6 年 前
コミット
bc88c194f9

+ 7
- 3
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackController.java ファイルの表示

203
             return;
203
             return;
204
         }
204
         }
205
 
205
 
206
+        peek().mergeOptions(mergeOptions);
207
+        Options disappearingOptions = resolveCurrentOptions();
208
+
206
         final ViewController disappearing = stack.pop();
209
         final ViewController disappearing = stack.pop();
207
         final ViewController appearing = stack.peek();
210
         final ViewController appearing = stack.peek();
208
-        disappearing.mergeOptions(mergeOptions);
211
+
209
         disappearing.onViewWillDisappear();
212
         disappearing.onViewWillDisappear();
210
         appearing.onViewWillAppear();
213
         appearing.onViewWillAppear();
214
+
211
         Options resolvedOptions = resolveCurrentOptions();
215
         Options resolvedOptions = resolveCurrentOptions();
212
         ViewGroup appearingView = appearing.getView();
216
         ViewGroup appearingView = appearing.getView();
213
         if (appearingView.getLayoutParams() == null) {
217
         if (appearingView.getLayoutParams() == null) {
218
             getView().addView(appearingView, 0);
222
             getView().addView(appearingView, 0);
219
         }
223
         }
220
         presenter.onChildWillAppear(appearing.options, disappearing.options);
224
         presenter.onChildWillAppear(appearing.options, disappearing.options);
221
-        if (disappearing.options.animations.pop.enabled.isTrueOrUndefined()) {
222
-            animator.pop(disappearing.getView(), resolvedOptions.animations.pop, () -> finishPopping(disappearing, listener));
225
+        if (disappearingOptions.animations.pop.enabled.isTrueOrUndefined()) {
226
+            animator.pop(disappearing.getView(), disappearingOptions.animations.pop, () -> finishPopping(disappearing, listener));
223
         } else {
227
         } else {
224
             finishPopping(disappearing, listener);
228
             finishPopping(disappearing, listener);
225
         }
229
         }

+ 31
- 1
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/stack/StackControllerTest.java ファイルの表示

1
 package com.reactnativenavigation.viewcontrollers.stack;
1
 package com.reactnativenavigation.viewcontrollers.stack;
2
 
2
 
3
+import android.animation.Animator;
3
 import android.app.Activity;
4
 import android.app.Activity;
4
 import android.content.Context;
5
 import android.content.Context;
5
 import android.view.View;
6
 import android.view.View;
13
 import com.reactnativenavigation.mocks.TitleBarReactViewCreatorMock;
14
 import com.reactnativenavigation.mocks.TitleBarReactViewCreatorMock;
14
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
15
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
15
 import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
16
 import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
17
+import com.reactnativenavigation.parse.AnimationOptions;
16
 import com.reactnativenavigation.parse.NestedAnimationsOptions;
18
 import com.reactnativenavigation.parse.NestedAnimationsOptions;
17
 import com.reactnativenavigation.parse.Options;
19
 import com.reactnativenavigation.parse.Options;
18
 import com.reactnativenavigation.parse.params.Bool;
20
 import com.reactnativenavigation.parse.params.Bool;
36
 import com.reactnativenavigation.views.topbar.TopBar;
38
 import com.reactnativenavigation.views.topbar.TopBar;
37
 
39
 
38
 import org.assertj.core.api.iterable.Extractor;
40
 import org.assertj.core.api.iterable.Extractor;
41
+import org.json.JSONException;
39
 import org.json.JSONObject;
42
 import org.json.JSONObject;
40
 import org.junit.Test;
43
 import org.junit.Test;
41
 import org.mockito.ArgumentCaptor;
44
 import org.mockito.ArgumentCaptor;
317
     }
320
     }
318
 
321
 
319
     @Test
322
     @Test
320
-    public void popDoesNothingWhenZeroOrOneChild() {
323
+    public void pop_doesNothingWhenZeroOrOneChild() {
321
         assertThat(uut.isEmpty()).isTrue();
324
         assertThat(uut.isEmpty()).isTrue();
322
         uut.pop(Options.EMPTY, new CommandListenerAdapter());
325
         uut.pop(Options.EMPTY, new CommandListenerAdapter());
323
         assertThat(uut.isEmpty()).isTrue();
326
         assertThat(uut.isEmpty()).isTrue();
327
         assertContainsOnlyId(child1.getId());
330
         assertContainsOnlyId(child1.getId());
328
     }
331
     }
329
 
332
 
333
+    @SuppressWarnings("MagicNumber")
334
+    @Test
335
+    public void pop_animationOptionsAreMergedCorrectlyToDisappearingChild() throws JSONException {
336
+        disablePushAnimation(child1, child2);
337
+
338
+        uut.push(child1, new CommandListenerAdapter());
339
+        uut.push(child2, new CommandListenerAdapter());
340
+
341
+        Options mergeOptions = new Options();
342
+        JSONObject content = new JSONObject();
343
+        JSONObject x = new JSONObject();
344
+        x.put("duration", 300);
345
+        x.put("from", 0);
346
+        x.put("to", 1000);
347
+        content.put("x", x);
348
+        mergeOptions.animations.pop.content = AnimationOptions.parse(content);
349
+
350
+        uut.pop(mergeOptions, new CommandListenerAdapter());
351
+        ArgumentCaptor<NestedAnimationsOptions> captor = ArgumentCaptor.forClass(NestedAnimationsOptions.class);
352
+        verify(animator, times(1)).pop(any(), captor.capture(), any());
353
+        Animator animator = captor.getValue().content
354
+                .getAnimation(mock(View.class))
355
+                .getChildAnimations()
356
+                .get(0);
357
+        assertThat(animator.getDuration()).isEqualTo(300);
358
+    }
359
+
330
     @Test
360
     @Test
331
     public void canPopWhenSizeIsMoreThanOne() {
361
     public void canPopWhenSizeIsMoreThanOne() {
332
         assertThat(uut.isEmpty()).isTrue();
362
         assertThat(uut.isEmpty()).isTrue();