Browse Source

BottomTabs refactor

Pass child ViewControllers in constructor and create tabs in constructor as well
Guy Carmeli 6 years ago
parent
commit
031015c806

+ 4
- 6
lib/android/app/src/main/java/com/reactnativenavigation/parse/LayoutFactory.java View File

152
     }
152
     }
153
 
153
 
154
     private ViewController createBottomTabs(LayoutNode node) {
154
     private ViewController createBottomTabs(LayoutNode node) {
155
-        final BottomTabsController tabsComponent = new BottomTabsController(activity, childRegistry, eventEmitter, new ImageLoader(), node.id, parseNodeOptions(node));
156
-		List<ViewController> tabs = new ArrayList<>();
157
-		for (int i = 0; i < node.children.size(); i++) {
155
+        List<ViewController> tabs = new ArrayList<>();
156
+        for (int i = 0; i < node.children.size(); i++) {
158
             tabs.add(create(node.children.get(i)));
157
             tabs.add(create(node.children.get(i)));
159
-		}
160
-		tabsComponent.setTabs(tabs);
161
-		return tabsComponent;
158
+        }
159
+        return new BottomTabsController(activity, tabs, childRegistry, eventEmitter, new ImageLoader(), node.id, parseNodeOptions(node));
162
 	}
160
 	}
163
 
161
 
164
     private ViewController createTopTabs(LayoutNode node) {
162
     private ViewController createTopTabs(LayoutNode node) {

+ 7
- 12
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsController.java View File

32
 public class BottomTabsController extends ParentController implements AHBottomNavigation.OnTabSelectedListener, TabSelector {
32
 public class BottomTabsController extends ParentController implements AHBottomNavigation.OnTabSelectedListener, TabSelector {
33
 
33
 
34
 	private BottomTabs bottomTabs;
34
 	private BottomTabs bottomTabs;
35
-	private List<ViewController> tabs = new ArrayList<>();
35
+	private List<ViewController> tabs;
36
     private EventEmitter eventEmitter;
36
     private EventEmitter eventEmitter;
37
     private ImageLoader imageLoader;
37
     private ImageLoader imageLoader;
38
     private BottomTabsOptionsPresenter presenter;
38
     private BottomTabsOptionsPresenter presenter;
39
     private final BottomTabFinder bottomTabFinder = new BottomTabFinder();
39
     private final BottomTabFinder bottomTabFinder = new BottomTabFinder();
40
 
40
 
41
-    public BottomTabsController(Activity activity, ChildControllersRegistry childRegistry, EventEmitter eventEmitter, ImageLoader imageLoader, String id, Options initialOptions) {
41
+    public BottomTabsController(Activity activity, List<ViewController> tabs, ChildControllersRegistry childRegistry, EventEmitter eventEmitter, ImageLoader imageLoader, String id, Options initialOptions) {
42
 		super(activity, childRegistry, id, initialOptions);
42
 		super(activity, childRegistry, id, initialOptions);
43
+        this.tabs = tabs;
43
         this.eventEmitter = eventEmitter;
44
         this.eventEmitter = eventEmitter;
44
         this.imageLoader = imageLoader;
45
         this.imageLoader = imageLoader;
46
+        createTabs(tabs);
45
     }
47
     }
46
 
48
 
47
 	@NonNull
49
 	@NonNull
102
         selectTab(index);
104
         selectTab(index);
103
         return true;
105
         return true;
104
 	}
106
 	}
105
-	
106
-	public void setTabs(final List<ViewController> tabs) {
107
+
108
+	private void createTabs(final List<ViewController> tabs) {
107
 		if (tabs.size() > 5) {
109
 		if (tabs.size() > 5) {
108
 			throw new RuntimeException("Too many tabs!");
110
 			throw new RuntimeException("Too many tabs!");
109
 		}
111
 		}
128
             public void onComplete(@NonNull List<Drawable> drawables) {
130
             public void onComplete(@NonNull List<Drawable> drawables) {
129
                 List<AHBottomNavigationItem> tabs = new ArrayList<>();
131
                 List<AHBottomNavigationItem> tabs = new ArrayList<>();
130
                 for (int i = 0; i < drawables.size(); i++) {
132
                 for (int i = 0; i < drawables.size(); i++) {
131
-                    AHBottomNavigationItem tab = createTab(bottomTabOptionsList.get(i), drawables.get(i));
132
-                    tabs.add(tab);
133
-
133
+                    tabs.add(new AHBottomNavigationItem(bottomTabOptionsList.get(i).title.get(""), drawables.get(i)));
134
                 }
134
                 }
135
                 bottomTabs.addItems(tabs);
135
                 bottomTabs.addItems(tabs);
136
                 bottomTabs.post(() -> {
136
                 bottomTabs.post(() -> {
149
 
149
 
150
 	}
150
 	}
151
 
151
 
152
-	private AHBottomNavigationItem createTab(final BottomTabOptions tabOptions, Drawable drawable) {
153
-        return  new AHBottomNavigationItem(tabOptions.title.get(""), drawable);
154
-
155
-	}
156
-
157
     public int getSelectedIndex() {
152
     public int getSelectedIndex() {
158
 		return bottomTabs.getCurrentItem();
153
 		return bottomTabs.getCurrentItem();
159
 	}
154
 	}

+ 28
- 51
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/BottomTabsControllerTest.java View File

31
 import org.mockito.Mockito;
31
 import org.mockito.Mockito;
32
 
32
 
33
 import java.util.Arrays;
33
 import java.util.Arrays;
34
-import java.util.Collections;
35
 import java.util.List;
34
 import java.util.List;
36
 
35
 
37
 import static org.assertj.core.api.Java6Assertions.assertThat;
36
 import static org.assertj.core.api.Java6Assertions.assertThat;
61
         activity = newActivity();
60
         activity = newActivity();
62
         childRegistry = new ChildControllersRegistry();
61
         childRegistry = new ChildControllersRegistry();
63
         eventEmitter = Mockito.mock(EventEmitter.class);
62
         eventEmitter = Mockito.mock(EventEmitter.class);
64
-        uut = spy(new BottomTabsController(activity, childRegistry, eventEmitter, imageLoaderMock, "uut", new Options()) {
65
-            @Override
66
-            public void ensureViewIsCreated() {
67
-                super.ensureViewIsCreated();
68
-                uut.getView().layout(0, 0, 1000, 1000);
69
-                uut.getBottomTabs().layout(0, 0, 1000, 100);
70
-            }
71
-        });
63
+
72
         child1 = spy(new SimpleViewController(activity, childRegistry, "child1", tabOptions));
64
         child1 = spy(new SimpleViewController(activity, childRegistry, "child1", tabOptions));
73
         child2 = spy(new SimpleViewController(activity, childRegistry, "child2", tabOptions));
65
         child2 = spy(new SimpleViewController(activity, childRegistry, "child2", tabOptions));
74
         child3 = spy(new SimpleViewController(activity, childRegistry, "child3", tabOptions));
66
         child3 = spy(new SimpleViewController(activity, childRegistry, "child3", tabOptions));
75
         child4 = spy(new SimpleViewController(activity, childRegistry, "child4", tabOptions));
67
         child4 = spy(new SimpleViewController(activity, childRegistry, "child4", tabOptions));
76
         child5 = spy(new SimpleViewController(activity, childRegistry, "child5", tabOptions));
68
         child5 = spy(new SimpleViewController(activity, childRegistry, "child5", tabOptions));
69
+        when(child5.handleBack(any())).thenReturn(true);
77
         tabs = createTabs();
70
         tabs = createTabs();
71
+
72
+        uut = new BottomTabsController(activity, tabs, childRegistry, eventEmitter, imageLoaderMock, "uut", new Options()) {
73
+            @Override
74
+            public void ensureViewIsCreated() {
75
+                super.ensureViewIsCreated();
76
+                uut.getView().layout(0, 0, 1000, 1000);
77
+                uut.getBottomTabs().layout(0, 0, 1000, 100);
78
+            }
79
+        };
78
     }
80
     }
79
 
81
 
80
     @Test
82
     @Test
85
 
87
 
86
     @Test(expected = RuntimeException.class)
88
     @Test(expected = RuntimeException.class)
87
     public void setTabs_ThrowWhenMoreThan5() {
89
     public void setTabs_ThrowWhenMoreThan5() {
88
-        List<ViewController> tabs = createTabs();
89
         tabs.add(new SimpleViewController(activity, childRegistry, "6", tabOptions));
90
         tabs.add(new SimpleViewController(activity, childRegistry, "6", tabOptions));
90
-        uut.setTabs(tabs);
91
+        new BottomTabsController(activity, tabs, childRegistry, eventEmitter, imageLoaderMock, "uut", new Options()) {
92
+            @Override
93
+            public void ensureViewIsCreated() {
94
+                super.ensureViewIsCreated();
95
+                uut.getView().layout(0, 0, 1000, 1000);
96
+                uut.getBottomTabs().layout(0, 0, 1000, 100);
97
+            }
98
+        };
91
     }
99
     }
92
 
100
 
93
     @Test
101
     @Test
94
     public void setTab_controllerIsSetAsParent() {
102
     public void setTab_controllerIsSetAsParent() {
95
-        List<ViewController> tabs = createTabs();
96
-        uut.setTabs(tabs);
97
         for (ViewController tab : tabs) {
103
         for (ViewController tab : tabs) {
98
             assertThat(tab.getParentController()).isEqualTo(uut);
104
             assertThat(tab.getParentController()).isEqualTo(uut);
99
         }
105
         }
101
 
107
 
102
     @Test
108
     @Test
103
     public void setTabs_AddAllViews() {
109
     public void setTabs_AddAllViews() {
104
-        List<ViewController> tabs = createTabs();
105
-        uut.setTabs(tabs);
106
         uut.onViewAppeared();
110
         uut.onViewAppeared();
107
         assertThat(uut.getView().getChildCount()).isEqualTo(2);
111
         assertThat(uut.getView().getChildCount()).isEqualTo(2);
108
         assertThat(((ViewController) ((List) uut.getChildControllers()).get(0)).getView().getParent()).isNotNull();
112
         assertThat(((ViewController) ((List) uut.getChildControllers()).get(0)).getView().getParent()).isNotNull();
110
 
114
 
111
     @Test
115
     @Test
112
     public void onTabSelected() {
116
     public void onTabSelected() {
113
-        uut.setTabs(createTabs());
114
         assertThat(uut.getSelectedIndex()).isZero();
117
         assertThat(uut.getSelectedIndex()).isZero();
115
 
118
 
116
         uut.onTabSelected(3, false);
119
         uut.onTabSelected(3, false);
122
 
125
 
123
     @Test
126
     @Test
124
     public void onTabReSelected() {
127
     public void onTabReSelected() {
125
-        uut.setTabs(createTabs());
126
         assertThat(uut.getSelectedIndex()).isZero();
128
         assertThat(uut.getSelectedIndex()).isZero();
127
 
129
 
128
         uut.onTabSelected(0, false);
130
         uut.onTabSelected(0, false);
132
         verify(eventEmitter, times(1)).emitBottomTabSelected(0, 0);
134
         verify(eventEmitter, times(1)).emitBottomTabSelected(0, 0);
133
     }
135
     }
134
 
136
 
135
-    @Test
136
-    public void findControllerById_ReturnsSelfOrChildren() {
137
-        assertThat(uut.findControllerById("123")).isNull();
138
-        assertThat(uut.findControllerById(uut.getId())).isEqualTo(uut);
139
-        StackController inner = createStack("inner");
140
-        inner.push(child1, new CommandListenerAdapter());
141
-        assertThat(uut.findControllerById(child1.getId())).isNull();
142
-        uut.setTabs(Collections.singletonList(inner));
143
-        assertThat(uut.findControllerById(child1.getId())).isEqualTo(child1);
144
-    }
145
-
146
     @Test
137
     @Test
147
     public void handleBack_DelegatesToSelectedChild() {
138
     public void handleBack_DelegatesToSelectedChild() {
148
         assertThat(uut.handleBack(new CommandListenerAdapter())).isFalse();
139
         assertThat(uut.handleBack(new CommandListenerAdapter())).isFalse();
149
-
150
-        List<ViewController> tabs = createTabs();
151
-        ViewController spy = spy(tabs.get(2));
152
-        tabs.set(2, spy);
153
-        when(spy.handleBack(any())).thenReturn(true);
154
-        uut.setTabs(tabs);
155
-
156
-        assertThat(uut.handleBack(new CommandListenerAdapter())).isFalse();
157
-        uut.selectTab(2);
140
+        uut.selectTab(4);
158
         assertThat(uut.handleBack(new CommandListenerAdapter())).isTrue();
141
         assertThat(uut.handleBack(new CommandListenerAdapter())).isTrue();
159
-
160
-        verify(spy, times(1)).handleBack(any());
142
+        verify(child5, times(1)).handleBack(any());
161
     }
143
     }
162
 
144
 
163
     @Test
145
     @Test
164
     public void applyOptions_bottomTabsOptionsAreClearedAfterApply() {
146
     public void applyOptions_bottomTabsOptionsAreClearedAfterApply() {
165
-        List<ViewController> tabs = createTabs();
166
-        child1.options.bottomTabsOptions.tabColor = new Color(android.graphics.Color.RED);
167
-        uut.setTabs(tabs);
147
+        Options options = new Options();
148
+        options.bottomTabsOptions.tabColor = new Color(android.graphics.Color.RED);
149
+        child1.mergeOptions(options);
168
         uut.ensureViewIsCreated();
150
         uut.ensureViewIsCreated();
169
 
151
 
170
         StackController stack = spy(createStack("stack"));
152
         StackController stack = spy(createStack("stack"));
181
 
163
 
182
     @Test
164
     @Test
183
     public void mergeOptions_currentTabIndex() {
165
     public void mergeOptions_currentTabIndex() {
184
-        uut.setTabs(tabs);
185
         uut.ensureViewIsCreated();
166
         uut.ensureViewIsCreated();
167
+        assertThat(uut.getSelectedIndex()).isZero();
186
 
168
 
187
         Options options = new Options();
169
         Options options = new Options();
188
         options.bottomTabsOptions.currentTabIndex = new Number(1);
170
         options.bottomTabsOptions.currentTabIndex = new Number(1);
189
         uut.mergeOptions(options);
171
         uut.mergeOptions(options);
190
-        verify(uut, times(1)).selectTab(1);
172
+        assertThat(uut.getSelectedIndex()).isOne();
191
         verify(eventEmitter, times(0)).emitBottomTabSelected(any(Integer.class), any(Integer.class));
173
         verify(eventEmitter, times(0)).emitBottomTabSelected(any(Integer.class), any(Integer.class));
192
     }
174
     }
193
 
175
 
194
     @Test
176
     @Test
195
     public void mergeOptions_drawBehind() {
177
     public void mergeOptions_drawBehind() {
196
-        List<ViewController> tabs = createTabs();
197
-        uut.setTabs(tabs);
198
         uut.ensureViewIsCreated();
178
         uut.ensureViewIsCreated();
199
         child1.onViewAppeared();
179
         child1.onViewAppeared();
200
         uut.selectTab(0);
180
         uut.selectTab(0);
214
 
194
 
215
     @Test
195
     @Test
216
     public void child_mergeOptions_currentTabIndex() {
196
     public void child_mergeOptions_currentTabIndex() {
217
-        List<ViewController> tabs = createTabs();
218
-        uut.setTabs(tabs);
219
         uut.ensureViewIsCreated();
197
         uut.ensureViewIsCreated();
220
 
198
 
221
         assertThat(uut.getSelectedIndex()).isZero();
199
         assertThat(uut.getSelectedIndex()).isZero();
229
 
207
 
230
     @Test
208
     @Test
231
     public void buttonPressInvokedOnCurrentTab() {
209
     public void buttonPressInvokedOnCurrentTab() {
232
-        uut.setTabs(createTabs());
233
         uut.ensureViewIsCreated();
210
         uut.ensureViewIsCreated();
234
-        uut.selectTab(1);
211
+        uut.selectTab(4);
235
 
212
 
236
         uut.sendOnNavigationButtonPressed("btn1");
213
         uut.sendOnNavigationButtonPressed("btn1");
237
-        verify(child2, times(1)).sendOnNavigationButtonPressed("btn1");
214
+        verify(child5, times(1)).sendOnNavigationButtonPressed("btn1");
238
     }
215
     }
239
 
216
 
240
     @NonNull
217
     @NonNull

+ 9
- 14
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/NavigatorTest.java View File

29
 import org.robolectric.android.controller.ActivityController;
29
 import org.robolectric.android.controller.ActivityController;
30
 
30
 
31
 import java.util.Arrays;
31
 import java.util.Arrays;
32
+import java.util.List;
32
 
33
 
33
 import static org.assertj.core.api.Java6Assertions.assertThat;
34
 import static org.assertj.core.api.Java6Assertions.assertThat;
34
 import static org.mockito.ArgumentMatchers.any;
35
 import static org.mockito.ArgumentMatchers.any;
120
 
121
 
121
     @Test
122
     @Test
122
     public void push_OnCorrectStackByFindingChildId() {
123
     public void push_OnCorrectStackByFindingChildId() {
123
-        BottomTabsController bottomTabsController = newTabs();
124
         StackController stack1 = newStack();
124
         StackController stack1 = newStack();
125
         StackController stack2 = newStack();
125
         StackController stack2 = newStack();
126
         stack1.push(child1, new CommandListenerAdapter());
126
         stack1.push(child1, new CommandListenerAdapter());
127
         stack2.push(child2, new CommandListenerAdapter());
127
         stack2.push(child2, new CommandListenerAdapter());
128
-        bottomTabsController.setTabs(Arrays.asList(stack1, stack2));
128
+        BottomTabsController bottomTabsController = newTabs(Arrays.asList(stack1, stack2));
129
         uut.setRoot(bottomTabsController, new CommandListenerAdapter());
129
         uut.setRoot(bottomTabsController, new CommandListenerAdapter());
130
 
130
 
131
         SimpleViewController newChild = new SimpleViewController(activity, childRegistry, "new child", tabOptions);
131
         SimpleViewController newChild = new SimpleViewController(activity, childRegistry, "new child", tabOptions);
145
 
145
 
146
     @Test
146
     @Test
147
     public void pop_FromCorrectStackByFindingChildId() {
147
     public void pop_FromCorrectStackByFindingChildId() {
148
-        BottomTabsController bottomTabsController = newTabs();
149
         StackController stack1 = newStack();
148
         StackController stack1 = newStack();
150
         StackController stack2 = newStack();
149
         StackController stack2 = newStack();
151
-        bottomTabsController.setTabs(Arrays.asList(stack1, stack2));
150
+        BottomTabsController bottomTabsController = newTabs(Arrays.asList(stack1, stack2));
152
         uut.setRoot(bottomTabsController, new CommandListenerAdapter());
151
         uut.setRoot(bottomTabsController, new CommandListenerAdapter());
153
         stack1.push(child1, new CommandListenerAdapter());
152
         stack1.push(child1, new CommandListenerAdapter());
154
         stack2.push(child2, new CommandListenerAdapter());
153
         stack2.push(child2, new CommandListenerAdapter());
169
 
168
 
170
     @Test
169
     @Test
171
     public void popSpecific() {
170
     public void popSpecific() {
172
-        BottomTabsController bottomTabsController = newTabs();
173
         StackController stack1 = newStack();
171
         StackController stack1 = newStack();
174
         StackController stack2 = newStack();
172
         StackController stack2 = newStack();
175
         stack1.push(child1, new CommandListenerAdapter());
173
         stack1.push(child1, new CommandListenerAdapter());
176
         stack2.push(child2, new CommandListenerAdapter());
174
         stack2.push(child2, new CommandListenerAdapter());
177
         stack2.push(child3, new CommandListenerAdapter());
175
         stack2.push(child3, new CommandListenerAdapter());
178
         stack2.push(child4, new CommandListenerAdapter());
176
         stack2.push(child4, new CommandListenerAdapter());
179
-        bottomTabsController.setTabs(Arrays.asList(stack1, stack2));
177
+        BottomTabsController bottomTabsController = newTabs(Arrays.asList(stack1, stack2));
180
         uut.setRoot(bottomTabsController, new CommandListenerAdapter());
178
         uut.setRoot(bottomTabsController, new CommandListenerAdapter());
181
 
179
 
182
         uut.popSpecific(child2.getId(), new CommandListenerAdapter());
180
         uut.popSpecific(child2.getId(), new CommandListenerAdapter());
186
 
184
 
187
     @Test
185
     @Test
188
     public void popTo_FromCorrectStackUpToChild() {
186
     public void popTo_FromCorrectStackUpToChild() {
189
-        BottomTabsController bottomTabsController = newTabs();
190
         StackController stack1 = newStack();
187
         StackController stack1 = newStack();
191
         StackController stack2 = newStack();
188
         StackController stack2 = newStack();
192
-        bottomTabsController.setTabs(Arrays.asList(stack1, stack2));
189
+        BottomTabsController bottomTabsController = newTabs(Arrays.asList(stack1, stack2));
193
         uut.setRoot(bottomTabsController, new CommandListenerAdapter());
190
         uut.setRoot(bottomTabsController, new CommandListenerAdapter());
194
 
191
 
195
         stack1.push(child1, new CommandListenerAdapter());
192
         stack1.push(child1, new CommandListenerAdapter());
207
 
204
 
208
     @Test
205
     @Test
209
     public void popToRoot() {
206
     public void popToRoot() {
210
-        BottomTabsController bottomTabsController = newTabs();
211
         StackController stack1 = newStack();
207
         StackController stack1 = newStack();
212
         StackController stack2 = newStack();
208
         StackController stack2 = newStack();
213
-        bottomTabsController.setTabs(Arrays.asList(stack1, stack2));
209
+        BottomTabsController bottomTabsController = newTabs(Arrays.asList(stack1, stack2));
214
         uut.setRoot(bottomTabsController, new CommandListenerAdapter());
210
         uut.setRoot(bottomTabsController, new CommandListenerAdapter());
215
 
211
 
216
         stack1.push(child1, new CommandListenerAdapter());
212
         stack1.push(child1, new CommandListenerAdapter());
277
     }
273
     }
278
 
274
 
279
     @NonNull
275
     @NonNull
280
-    private BottomTabsController newTabs() {
281
-        return new BottomTabsController(activity, childRegistry, eventEmitter, imageLoaderMock, "tabsController", new Options());
276
+    private BottomTabsController newTabs(List<ViewController> tabs) {
277
+        return new BottomTabsController(activity, tabs, childRegistry, eventEmitter, imageLoaderMock, "tabsController", new Options());
282
     }
278
     }
283
 
279
 
284
     @NonNull
280
     @NonNull
338
 
334
 
339
     @Test
335
     @Test
340
     public void pop_FromCorrectStackByFindingChildId_Promise() {
336
     public void pop_FromCorrectStackByFindingChildId_Promise() {
341
-        BottomTabsController bottomTabsController = newTabs();
342
         StackController stack1 = newStack();
337
         StackController stack1 = newStack();
343
         final StackController stack2 = newStack();
338
         final StackController stack2 = newStack();
344
-        bottomTabsController.setTabs(Arrays.asList(stack1, stack2));
339
+        BottomTabsController bottomTabsController = newTabs(Arrays.asList(stack1, stack2));
345
         uut.setRoot(bottomTabsController, new CommandListenerAdapter());
340
         uut.setRoot(bottomTabsController, new CommandListenerAdapter());
346
 
341
 
347
         stack1.push(child1, new CommandListenerAdapter());
342
         stack1.push(child1, new CommandListenerAdapter());