Browse Source

Add back button before view is created

This prevents the back button from being added too early when pushing screens.
If the back button is added before the actual push (current behaviour) the the previous screen's
title moves unexpectedly to make space for the back button.
Guy Carmeli 6 years ago
parent
commit
d8c1751c05

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

101
     @CallSuper
101
     @CallSuper
102
     public void mergeOptions(Options options) {
102
     public void mergeOptions(Options options) {
103
         this.options = this.options.mergeWith(options);
103
         this.options = this.options.mergeWith(options);
104
-        applyOptions(this.options);
104
+        if (view != null) applyOptions(this.options);
105
         this.options.clearOneTimeOptions();
105
         this.options.clearOneTimeOptions();
106
     }
106
     }
107
 
107
 

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

5
 import com.reactnativenavigation.viewcontrollers.ViewController;
5
 import com.reactnativenavigation.viewcontrollers.ViewController;
6
 
6
 
7
 public class BackButtonHelper {
7
 public class BackButtonHelper {
8
-    public void addToPushedChild(StackController stack, ViewController child) {
9
-        if (stack.size() <= 1 || child.options.topBar.buttons.left != null || child.options.topBar.buttons.back.visible.isFalse()) return;
8
+    public void addToPushedChild(ViewController child) {
9
+        if (child.options.topBar.buttons.left != null || child.options.topBar.buttons.back.visible.isFalse()) return;
10
         Options options = new Options();
10
         Options options = new Options();
11
         options.topBar.buttons.back.setVisible();
11
         options.topBar.buttons.back.setVisible();
12
         child.mergeOptions(options);
12
         child.mergeOptions(options);

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

129
 
129
 
130
     public void push(ViewController child, CommandListener listener) {
130
     public void push(ViewController child, CommandListener listener) {
131
         final ViewController toRemove = stack.peek();
131
         final ViewController toRemove = stack.peek();
132
+        backButtonHelper.addToPushedChild(child);
132
         child.setParentController(this);
133
         child.setParentController(this);
133
         stack.push(child.getId(), child);
134
         stack.push(child.getId(), child);
134
-        backButtonHelper.addToPushedChild(this, child);
135
         Options resolvedOptions = resolveCurrentOptions(presenter.getDefaultOptions());
135
         Options resolvedOptions = resolveCurrentOptions(presenter.getDefaultOptions());
136
         addChildToStack(child, child.getView(), resolvedOptions);
136
         addChildToStack(child, child.getView(), resolvedOptions);
137
 
137
 

+ 3
- 3
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/stack/BackButtonHelperTest.java View File

41
     }
41
     }
42
 
42
 
43
     @Test
43
     @Test
44
-    public void addToChild_doesNotAddIfStackContainsOneChild() {
45
-        uut.addToPushedChild(stack, child1);
46
-        verify(child1, times(0)).mergeOptions(any());
44
+    public void addToChild() {
45
+        uut.addToPushedChild(child1);
46
+        verify(child1).mergeOptions(any());
47
     }
47
     }
48
 
48
 
49
     @Test
49
     @Test

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

38
 import org.json.JSONObject;
38
 import org.json.JSONObject;
39
 import org.junit.Test;
39
 import org.junit.Test;
40
 import org.mockito.ArgumentCaptor;
40
 import org.mockito.ArgumentCaptor;
41
+import org.mockito.InOrder;
41
 import org.mockito.Mockito;
42
 import org.mockito.Mockito;
42
 
43
 
43
 import java.util.ArrayList;
44
 import java.util.ArrayList;
48
 import static org.assertj.core.api.Java6Assertions.assertThat;
49
 import static org.assertj.core.api.Java6Assertions.assertThat;
49
 import static org.mockito.ArgumentMatchers.any;
50
 import static org.mockito.ArgumentMatchers.any;
50
 import static org.mockito.ArgumentMatchers.eq;
51
 import static org.mockito.ArgumentMatchers.eq;
52
+import static org.mockito.Mockito.inOrder;
51
 import static org.mockito.Mockito.mock;
53
 import static org.mockito.Mockito.mock;
52
 import static org.mockito.Mockito.spy;
54
 import static org.mockito.Mockito.spy;
53
 import static org.mockito.Mockito.times;
55
 import static org.mockito.Mockito.times;
65
     private NavigationAnimator animator;
67
     private NavigationAnimator animator;
66
     private TopBarController topBarController;
68
     private TopBarController topBarController;
67
     private StackOptionsPresenter presenter;
69
     private StackOptionsPresenter presenter;
70
+    private BackButtonHelper backButtonHelper;
68
 
71
 
69
     @Override
72
     @Override
70
     public void beforeEach() {
73
     public void beforeEach() {
71
         super.beforeEach();
74
         super.beforeEach();
72
         animator = Mockito.mock(NavigationAnimator.class);
75
         animator = Mockito.mock(NavigationAnimator.class);
76
+        backButtonHelper = spy(new BackButtonHelper());
73
         activity = newActivity();
77
         activity = newActivity();
74
         childRegistry = new ChildControllersRegistry();
78
         childRegistry = new ChildControllersRegistry();
75
         presenter = spy(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new Options()));
79
         presenter = spy(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new Options()));
121
         verify(listener, times(1)).onSuccess(child1.getId());
125
         verify(listener, times(1)).onSuccess(child1.getId());
122
     }
126
     }
123
 
127
 
124
-    @Test
125
-    public void push_backButtonIsAddedIfStackContainsMoreThenOneScreen() {
126
-        uut.push(child1, new CommandListenerAdapter());
127
-        verify(child1, times(0)).mergeOptions(any());
128
-        assertThat(child1.options.topBar.buttons.back.visible.isFalseOrUndefined()).isTrue();
129
-
130
-        uut.push(child2, new CommandListenerAdapter());
131
-        ArgumentCaptor<Options> captor = ArgumentCaptor.forClass(Options.class);
132
-        verify(child2, times(1)).mergeOptions(captor.capture());
133
-        assertThat(captor.getValue().topBar.buttons.back.visible.get()).isTrue();
134
-    }
135
-
136
     @Test
128
     @Test
137
     public void push_backButtonIsNotAddedIfScreenContainsLeftButton() {
129
     public void push_backButtonIsNotAddedIfScreenContainsLeftButton() {
138
         disablePushAnimation(child1, child2);
130
         disablePushAnimation(child1, child2);
157
         verify(child1, times(0)).mergeOptions(any());
149
         verify(child1, times(0)).mergeOptions(any());
158
     }
150
     }
159
 
151
 
152
+    @Test
153
+    public void push_backButtonAddedBeforeChildViewIsCreated() {
154
+        disablePopAnimation(child1, child2);
155
+        uut.push(child1, new CommandListenerAdapter());
156
+        uut.push(child2, new CommandListenerAdapter());
157
+
158
+        InOrder inOrder = inOrder(backButtonHelper, child2);
159
+        inOrder.verify(backButtonHelper).addToPushedChild(child2);
160
+        inOrder.verify(child2).setParentController(uut);
161
+        inOrder.verify(child2).getView(); // creates view
162
+    }
163
+
160
     @Test
164
     @Test
161
     public void push_waitForRender() {
165
     public void push_waitForRender() {
162
         disablePushAnimation(child1);
166
         disablePushAnimation(child1);
845
                 .setChildRegistry(childRegistry)
849
                 .setChildRegistry(childRegistry)
846
                 .setAnimator(animator)
850
                 .setAnimator(animator)
847
                 .setStackPresenter(presenter)
851
                 .setStackPresenter(presenter)
852
+                .setBackButtonHelper(backButtonHelper)
848
                 .build();
853
                 .build();
849
     }
854
     }
850
 
855