Browse Source

Use four spaces indentation

OCD made me do it.
Guy Carmeli 7 years ago
parent
commit
2531c08905

+ 484
- 484
android/app/src/main/java/com/reactnativenavigation/layouts/BottomTabsLayout.java View File

@@ -46,488 +46,488 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
46 46
 @SuppressLint("ViewConstructor")
47 47
 public class BottomTabsLayout extends BaseLayout implements AHBottomNavigation.OnTabSelectedListener {
48 48
 
49
-	private ActivityParams params;
50
-	private SnackbarAndFabContainer snackbarAndFabContainer;
51
-	private BottomTabs bottomTabs;
52
-	private ScreenStack[] screenStacks;
53
-	private final SideMenuParams leftSideMenuParams;
54
-	private final SideMenuParams rightSideMenuParams;
55
-	private final SlidingOverlaysQueue slidingOverlaysQueue = new SlidingOverlaysQueue();
56
-	private
57
-	@Nullable
58
-	SideMenu sideMenu;
59
-	private int currentStackIndex = 0;
60
-	private LightBox lightBox;
61
-
62
-	public BottomTabsLayout(AppCompatActivity activity, ActivityParams params) {
63
-		super(activity);
64
-		this.params = params;
65
-		leftSideMenuParams = params.leftSideMenuParams;
66
-		rightSideMenuParams = params.rightSideMenuParams;
67
-		screenStacks = new ScreenStack[params.tabParams.size()];
68
-		createLayout();
69
-	}
70
-
71
-	private void createLayout() {
72
-		createSideMenu();
73
-		createBottomTabs();
74
-		addBottomTabs();
75
-		addScreenStacks();
76
-		createSnackbarContainer();
77
-		showInitialScreenStack();
78
-	}
79
-
80
-	private void createSideMenu() {
81
-		if (leftSideMenuParams == null && rightSideMenuParams == null) {
82
-			return;
83
-		}
84
-		sideMenu = new SideMenu(getContext(), leftSideMenuParams, rightSideMenuParams);
85
-		RelativeLayout.LayoutParams lp = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
86
-		addView(sideMenu, lp);
87
-	}
88
-
89
-	private void addScreenStacks() {
90
-		for (int i = screenStacks.length - 1; i >= 0; i--) {
91
-			createAndAddScreens(i);
92
-		}
93
-	}
94
-
95
-	private void createAndAddScreens(int position) {
96
-		ScreenParams screenParams = params.tabParams.get(position);
97
-		ScreenStack newStack = new ScreenStack(getActivity(), getScreenStackParent(), screenParams.getNavigatorId(), this);
98
-		newStack.pushInitialScreen(screenParams, createScreenLayoutParams(screenParams));
99
-		screenStacks[position] = newStack;
100
-	}
101
-
102
-	private RelativeLayout getScreenStackParent() {
103
-		return sideMenu == null ? this : sideMenu.getContentContainer();
104
-	}
105
-
106
-	@NonNull
107
-	private LayoutParams createScreenLayoutParams(ScreenParams params) {
108
-		LayoutParams lp = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
109
-		if (params.styleParams.drawScreenAboveBottomTabs) {
110
-			lp.addRule(RelativeLayout.ABOVE, bottomTabs.getId());
111
-		}
112
-		return lp;
113
-	}
114
-
115
-	private void createBottomTabs() {
116
-		bottomTabs = new BottomTabs(getContext());
117
-		bottomTabs.addTabs(params.tabParams, this);
118
-	}
119
-
120
-	private void addBottomTabs() {
121
-		LayoutParams lp = new LayoutParams(MATCH_PARENT, WRAP_CONTENT);
122
-		lp.addRule(ALIGN_PARENT_BOTTOM);
123
-		getScreenStackParent().addView(bottomTabs, lp);
124
-	}
125
-
126
-	private void createSnackbarContainer() {
127
-		snackbarAndFabContainer = new SnackbarAndFabContainer(getContext(), this);
128
-		RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
129
-		alignSnackbarContainerWithBottomTabs(lp, getCurrentScreen().getStyleParams());
130
-		snackbarAndFabContainer.setClickable(false);
131
-		getScreenStackParent().addView(snackbarAndFabContainer, lp);
132
-	}
133
-
134
-	private void showInitialScreenStack() {
135
-		showStackAndUpdateStyle(screenStacks[0]);
136
-		EventBus.instance.post(new ScreenChangedEvent(screenStacks[0].peek().getScreenParams()));
137
-	}
138
-
139
-	@Override
140
-	public View asView() {
141
-		return this;
142
-	}
143
-
144
-	@Override
145
-	public boolean onBackPressed() {
146
-		if (getCurrentScreenStack().handleBackPressInJs()) {
147
-			return true;
148
-		}
149
-
150
-		if (getCurrentScreenStack().canPop()) {
151
-			getCurrentScreenStack().pop(true);
152
-			setBottomTabsStyleFromCurrentScreen();
153
-			EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
154
-			return true;
155
-		} else {
156
-			return false;
157
-		}
158
-	}
159
-
160
-	@Override
161
-	public void setTopBarVisible(String screenInstanceId, boolean hidden, boolean animated) {
162
-		for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
163
-			screenStacks[i].setScreenTopBarVisible(screenInstanceId, hidden, animated);
164
-		}
165
-	}
166
-
167
-	public void setBottomTabsVisible(boolean hidden, boolean animated) {
168
-		bottomTabs.setVisibility(hidden, animated);
169
-	}
170
-
171
-	@Override
172
-	public void setTitleBarTitle(String screenInstanceId, String title) {
173
-		for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
174
-			screenStacks[i].setScreenTitleBarTitle(screenInstanceId, title);
175
-		}
176
-	}
177
-
178
-	@Override
179
-	public void setTitleBarSubtitle(String screenInstanceId, String subtitle) {
180
-		for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
181
-			screenStacks[i].setScreenTitleBarSubtitle(screenInstanceId, subtitle);
182
-		}
183
-	}
184
-
185
-	@Override
186
-	public void setTitleBarRightButtons(String screenInstanceId, String navigatorEventId, List<TitleBarButtonParams> titleBarButtons) {
187
-		for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
188
-			screenStacks[i].setScreenTitleBarRightButtons(screenInstanceId, navigatorEventId, titleBarButtons);
189
-		}
190
-	}
191
-
192
-	@Override
193
-	public void setTitleBarLeftButton(String screenInstanceId, String navigatorEventId, TitleBarLeftButtonParams titleBarLeftButtonParams) {
194
-		for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
195
-			screenStacks[i].setScreenTitleBarLeftButton(screenInstanceId, navigatorEventId, titleBarLeftButtonParams);
196
-		}
197
-	}
198
-
199
-	@Override
200
-	public void setFab(String screenInstanceId, String navigatorEventId, FabParams fabParams) {
201
-		for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
202
-			screenStacks[i].setFab(screenInstanceId, fabParams);
203
-		}
204
-	}
205
-
206
-	@Override
207
-	public void updateScreenStyle(String screenInstanceId, Bundle styleParams) {
208
-		for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
209
-			screenStacks[i].updateScreenStyle(screenInstanceId, styleParams);
210
-		}
211
-	}
212
-
213
-	@Override
214
-	public void selectTopTabByTabIndex(String screenInstanceId, int index) {
215
-		for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
216
-			screenStacks[i].selectTopTabByTabIndex(screenInstanceId, index);
217
-		}
218
-	}
219
-
220
-	@Override
221
-	public void selectTopTabByScreen(String screenInstanceId) {
222
-		for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
223
-			screenStacks[i].selectTopTabByScreen(screenInstanceId);
224
-		}
225
-	}
226
-
227
-	@Override
228
-	public void toggleSideMenuVisible(boolean animated, Side side) {
229
-		if (sideMenu != null) {
230
-			sideMenu.toggleVisible(animated, side);
231
-		}
232
-	}
233
-
234
-	@Override
235
-	public void setSideMenuVisible(boolean animated, boolean visible, Side side) {
236
-		if (sideMenu != null) {
237
-			sideMenu.setVisible(visible, animated, side);
238
-		}
239
-	}
240
-
241
-	@Override
242
-	public void setSideMenuEnabled(boolean enabled, Side side) {
243
-		if (sideMenu != null) {
244
-			sideMenu.setDrawerLockMode(enabled ? DrawerLayout.LOCK_MODE_UNLOCKED : DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
245
-		}
246
-	}
247
-
248
-	@Override
249
-	public void showSnackbar(SnackbarParams params) {
250
-		final String eventId = getCurrentScreenStack().peek().getNavigatorEventId();
251
-		snackbarAndFabContainer.showSnackbar(eventId, params);
252
-	}
253
-
254
-	@Override
255
-	public void dismissSnackbar() {
256
-		snackbarAndFabContainer.dismissSnackbar();
257
-	}
258
-
259
-	@Override
260
-	public void showLightBox(LightBoxParams params) {
261
-		if (lightBox == null) {
262
-			lightBox = new LightBox(getActivity(), new Runnable() {
263
-				@Override
264
-				public void run() {
265
-					lightBox = null;
266
-				}
267
-			}, params);
268
-			lightBox.show();
269
-		}
270
-	}
271
-
272
-	@Override
273
-	public void dismissLightBox() {
274
-		if (lightBox != null) {
275
-			lightBox.hide();
276
-			lightBox = null;
277
-		}
278
-	}
279
-
280
-	@Override
281
-	public void showSlidingOverlay(final SlidingOverlayParams params) {
282
-		slidingOverlaysQueue.add(new SlidingOverlay(this, params));
283
-	}
284
-
285
-	@Override
286
-	public void hideSlidingOverlay() {
287
-		slidingOverlaysQueue.remove();
288
-	}
289
-
290
-	@Override
291
-	public void onModalDismissed() {
292
-		EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
293
-	}
294
-
295
-	@Override
296
-	public boolean containsNavigator(String navigatorId) {
297
-		// Unused
298
-		return false;
299
-	}
300
-
301
-	@Override
302
-	public void showContextualMenu(String screenInstanceId, ContextualMenuParams params, Callback onButtonClicked) {
303
-		getCurrentScreenStack().peek().showContextualMenu(params, onButtonClicked);
304
-	}
305
-
306
-	@Override
307
-	public void dismissContextualMenu(String screenInstanceId) {
308
-		getCurrentScreenStack().peek().dismissContextualMenu();
309
-	}
310
-
311
-	@Override
312
-	public Screen getCurrentScreen() {
313
-		return getCurrentScreenStack().peek();
314
-	}
315
-
316
-	public void selectBottomTabByTabIndex(Integer index) {
317
-		bottomTabs.setCurrentItem(index);
318
-	}
319
-
320
-	public void selectBottomTabByNavigatorId(String navigatorId) {
321
-		bottomTabs.setCurrentItem(getScreenStackIndex(navigatorId));
322
-	}
323
-
324
-	private boolean hasBackgroundColor(StyleParams params) {
325
-		return params.screenBackgroundColor != null &&
326
-				params.screenBackgroundColor.hasColor();
327
-	}
328
-
329
-	private void setStyleFromScreen(StyleParams params) {
330
-		bottomTabs.setStyleFromScreen(params);
331
-		if (snackbarAndFabContainer != null && snackbarAndFabContainer.getLayoutParams() instanceof RelativeLayout.LayoutParams)
332
-			alignSnackbarContainerWithBottomTabs((LayoutParams) snackbarAndFabContainer.getLayoutParams(), params);
333
-		if (hasBackgroundColor(params)) {
334
-			asView().setBackgroundColor(params.screenBackgroundColor.getColor());
335
-		}
336
-	}
337
-
338
-	@Override
339
-	public void push(ScreenParams params) {
340
-		ScreenStack screenStack = getScreenStack(params.getNavigatorId());
341
-		screenStack.push(params, createScreenLayoutParams(params));
342
-		setStyleFromScreen(params.styleParams);
343
-		if (isCurrentStack(screenStack)) {
344
-			alignSnackbarContainerWithBottomTabs((LayoutParams) snackbarAndFabContainer.getLayoutParams(), params.styleParams);
345
-			EventBus.instance.post(new ScreenChangedEvent(params));
346
-		}
347
-	}
348
-
349
-	@Override
350
-	public void pop(final ScreenParams params) {
351
-		getCurrentScreenStack().pop(params.animateScreenTransitions, new ScreenStack.OnScreenPop() {
352
-			@Override
353
-			public void onScreenPopAnimationEnd() {
354
-				setBottomTabsStyleFromCurrentScreen();
355
-				alignSnackbarContainerWithBottomTabs((LayoutParams) snackbarAndFabContainer.getLayoutParams(), params.styleParams);
356
-				EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
357
-			}
358
-		});
359
-	}
360
-
361
-	@Override
362
-	public void popToRoot(final ScreenParams params) {
363
-		getCurrentScreenStack().popToRoot(params.animateScreenTransitions, new ScreenStack.OnScreenPop() {
364
-			@Override
365
-			public void onScreenPopAnimationEnd() {
366
-				setBottomTabsStyleFromCurrentScreen();
367
-				alignSnackbarContainerWithBottomTabs((LayoutParams) snackbarAndFabContainer.getLayoutParams(), params.styleParams);
368
-				EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
369
-			}
370
-		});
371
-	}
372
-
373
-	@Override
374
-	public void newStack(final ScreenParams params) {
375
-		ScreenStack screenStack = getScreenStack(params.getNavigatorId());
376
-		screenStack.newStack(params, createScreenLayoutParams(params));
377
-		if (isCurrentStack(screenStack)) {
378
-			setStyleFromScreen(params.styleParams);
379
-			alignSnackbarContainerWithBottomTabs((LayoutParams) snackbarAndFabContainer.getLayoutParams(), params.styleParams);
380
-			EventBus.instance.post(new ScreenChangedEvent(params));
381
-		}
382
-	}
383
-
384
-	private void alignSnackbarContainerWithBottomTabs(LayoutParams lp, StyleParams styleParams) {
385
-		if (styleParams.drawScreenAboveBottomTabs || !styleParams.bottomTabsHidden) {
386
-			lp.addRule(ABOVE, bottomTabs.getId());
387
-		} else {
388
-			ViewUtils.removeRuleCompat(lp, ABOVE);
389
-		}
390
-	}
391
-
392
-	@Override
393
-	public void destroy() {
394
-		snackbarAndFabContainer.destroy();
395
-		for (ScreenStack screenStack : screenStacks) {
396
-			screenStack.destroy();
397
-		}
398
-		if (sideMenu != null) {
399
-			sideMenu.destroy();
400
-		}
401
-		if (lightBox != null) {
402
-			lightBox.destroy();
403
-			lightBox = null;
404
-		}
405
-		slidingOverlaysQueue.destroy();
406
-	}
407
-
408
-	@Override
409
-	public boolean onTabSelected(int position, boolean wasSelected) {
410
-		if (wasSelected) {
411
-			sendTabReselectedEventToJs();
412
-			return false;
413
-		}
414
-
415
-		final int unselectedTabIndex = currentStackIndex;
416
-		hideCurrentStack();
417
-		showNewStack(position);
418
-		EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
419
-		sendTabSelectedEventToJs(position, unselectedTabIndex);
420
-		return true;
421
-	}
422
-
423
-	private void sendTabSelectedEventToJs(int selectedTabIndex, int unselectedTabIndex) {
424
-		String navigatorEventId = getCurrentScreenStack().peek().getNavigatorEventId();
425
-		WritableMap data = createTabSelectedEventData(selectedTabIndex, unselectedTabIndex);
426
-		NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("bottomTabSelected", navigatorEventId, data);
427
-
428
-		data = createTabSelectedEventData(selectedTabIndex, unselectedTabIndex);
429
-		NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("bottomTabSelected", data);
430
-	}
431
-
432
-	private WritableMap createTabSelectedEventData(int selectedTabIndex, int unselectedTabIndex) {
433
-		WritableMap data = Arguments.createMap();
434
-		data.putInt("selectedTabIndex", selectedTabIndex);
435
-		data.putInt("unselectedTabIndex", unselectedTabIndex);
436
-		return data;
437
-	}
438
-
439
-	private void sendTabReselectedEventToJs() {
440
-		WritableMap data = Arguments.createMap();
441
-		String navigatorEventId = getCurrentScreenStack().peek().getNavigatorEventId();
442
-		NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("bottomTabReselected", navigatorEventId, data);
443
-	}
444
-
445
-	private void showNewStack(int position) {
446
-		showStackAndUpdateStyle(screenStacks[position]);
447
-		currentStackIndex = position;
448
-	}
449
-
450
-	private void showStackAndUpdateStyle(ScreenStack newStack) {
451
-		newStack.show();
452
-		setStyleFromScreen(newStack.getCurrentScreenStyleParams());
453
-	}
454
-
455
-	private void hideCurrentStack() {
456
-		ScreenStack currentScreenStack = getCurrentScreenStack();
457
-		currentScreenStack.hide();
458
-	}
459
-
460
-	private ScreenStack getCurrentScreenStack() {
461
-		return screenStacks[currentStackIndex];
462
-	}
463
-
464
-	private
465
-	@NonNull
466
-	ScreenStack getScreenStack(String navigatorId) {
467
-		int index = getScreenStackIndex(navigatorId);
468
-		return screenStacks[index];
469
-	}
470
-
471
-	public void setBottomTabBadgeByIndex(Integer index, String badge) {
472
-		bottomTabs.setNotification(badge, index);
473
-	}
474
-
475
-	public void setBottomTabBadgeByNavigatorId(String navigatorId, String badge) {
476
-		bottomTabs.setNotification(badge, getScreenStackIndex(navigatorId));
477
-	}
478
-
479
-	public void setBottomTabButtonByIndex(Integer index, ScreenParams params) {
480
-		bottomTabs.setTabButton(params, index);
481
-	}
482
-
483
-	public void setBottomTabButtonByNavigatorId(String navigatorId, ScreenParams params) {
484
-		bottomTabs.setTabButton(params, getScreenStackIndex(navigatorId));
485
-	}
486
-
487
-	private int getScreenStackIndex(String navigatorId) throws ScreenStackNotFoundException {
488
-		for (int i = 0; i < screenStacks.length; i++) {
489
-			if (screenStacks[i].getNavigatorId().equals(navigatorId)) {
490
-				return i;
491
-			}
492
-		}
493
-		throw new ScreenStackNotFoundException("Stack " + navigatorId + " not found");
494
-	}
495
-
496
-	private class ScreenStackNotFoundException extends RuntimeException {
497
-		ScreenStackNotFoundException(String navigatorId) {
498
-			super(navigatorId);
499
-		}
500
-	}
501
-
502
-	private boolean isCurrentStack(ScreenStack screenStack) {
503
-		return getCurrentScreenStack() == screenStack;
504
-	}
505
-
506
-	private void setBottomTabsStyleFromCurrentScreen() {
507
-		setStyleFromScreen(getCurrentScreenStack().getCurrentScreenStyleParams());
508
-	}
509
-
510
-	@Override
511
-	public boolean onTitleBarBackButtonClick() {
512
-		if (getCurrentScreenStack().canPop()) {
513
-			getCurrentScreenStack().pop(true, new ScreenStack.OnScreenPop() {
514
-				@Override
515
-				public void onScreenPopAnimationEnd() {
516
-					setBottomTabsStyleFromCurrentScreen();
517
-					EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
518
-				}
519
-			});
520
-			return true;
521
-		}
522
-		return false;
523
-	}
524
-
525
-	@Override
526
-	public void onSideMenuButtonClick() {
527
-		final String navigatorEventId = getCurrentScreenStack().peek().getNavigatorEventId();
528
-		NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("sideMenu", navigatorEventId);
529
-		if (sideMenu != null) {
530
-			sideMenu.openDrawer(Side.Left);
531
-		}
532
-	}
49
+    private ActivityParams params;
50
+    private SnackbarAndFabContainer snackbarAndFabContainer;
51
+    private BottomTabs bottomTabs;
52
+    private ScreenStack[] screenStacks;
53
+    private final SideMenuParams leftSideMenuParams;
54
+    private final SideMenuParams rightSideMenuParams;
55
+    private final SlidingOverlaysQueue slidingOverlaysQueue = new SlidingOverlaysQueue();
56
+    private
57
+    @Nullable
58
+    SideMenu sideMenu;
59
+    private int currentStackIndex = 0;
60
+    private LightBox lightBox;
61
+
62
+    public BottomTabsLayout(AppCompatActivity activity, ActivityParams params) {
63
+        super(activity);
64
+        this.params = params;
65
+        leftSideMenuParams = params.leftSideMenuParams;
66
+        rightSideMenuParams = params.rightSideMenuParams;
67
+        screenStacks = new ScreenStack[params.tabParams.size()];
68
+        createLayout();
69
+    }
70
+
71
+    private void createLayout() {
72
+        createSideMenu();
73
+        createBottomTabs();
74
+        addBottomTabs();
75
+        addScreenStacks();
76
+        createSnackbarContainer();
77
+        showInitialScreenStack();
78
+    }
79
+
80
+    private void createSideMenu() {
81
+        if (leftSideMenuParams == null && rightSideMenuParams == null) {
82
+            return;
83
+        }
84
+        sideMenu = new SideMenu(getContext(), leftSideMenuParams, rightSideMenuParams);
85
+        RelativeLayout.LayoutParams lp = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
86
+        addView(sideMenu, lp);
87
+    }
88
+
89
+    private void addScreenStacks() {
90
+        for (int i = screenStacks.length - 1; i >= 0; i--) {
91
+            createAndAddScreens(i);
92
+        }
93
+    }
94
+
95
+    private void createAndAddScreens(int position) {
96
+        ScreenParams screenParams = params.tabParams.get(position);
97
+        ScreenStack newStack = new ScreenStack(getActivity(), getScreenStackParent(), screenParams.getNavigatorId(), this);
98
+        newStack.pushInitialScreen(screenParams, createScreenLayoutParams(screenParams));
99
+        screenStacks[position] = newStack;
100
+    }
101
+
102
+    private RelativeLayout getScreenStackParent() {
103
+        return sideMenu == null ? this : sideMenu.getContentContainer();
104
+    }
105
+
106
+    @NonNull
107
+    private LayoutParams createScreenLayoutParams(ScreenParams params) {
108
+        LayoutParams lp = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
109
+        if (params.styleParams.drawScreenAboveBottomTabs) {
110
+            lp.addRule(RelativeLayout.ABOVE, bottomTabs.getId());
111
+        }
112
+        return lp;
113
+    }
114
+
115
+    private void createBottomTabs() {
116
+        bottomTabs = new BottomTabs(getContext());
117
+        bottomTabs.addTabs(params.tabParams, this);
118
+    }
119
+
120
+    private void addBottomTabs() {
121
+        LayoutParams lp = new LayoutParams(MATCH_PARENT, WRAP_CONTENT);
122
+        lp.addRule(ALIGN_PARENT_BOTTOM);
123
+        getScreenStackParent().addView(bottomTabs, lp);
124
+    }
125
+
126
+    private void createSnackbarContainer() {
127
+        snackbarAndFabContainer = new SnackbarAndFabContainer(getContext(), this);
128
+        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
129
+        alignSnackbarContainerWithBottomTabs(lp, getCurrentScreen().getStyleParams());
130
+        snackbarAndFabContainer.setClickable(false);
131
+        getScreenStackParent().addView(snackbarAndFabContainer, lp);
132
+    }
133
+
134
+    private void showInitialScreenStack() {
135
+        showStackAndUpdateStyle(screenStacks[0]);
136
+        EventBus.instance.post(new ScreenChangedEvent(screenStacks[0].peek().getScreenParams()));
137
+    }
138
+
139
+    @Override
140
+    public View asView() {
141
+        return this;
142
+    }
143
+
144
+    @Override
145
+    public boolean onBackPressed() {
146
+        if (getCurrentScreenStack().handleBackPressInJs()) {
147
+            return true;
148
+        }
149
+
150
+        if (getCurrentScreenStack().canPop()) {
151
+            getCurrentScreenStack().pop(true);
152
+            setBottomTabsStyleFromCurrentScreen();
153
+            EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
154
+            return true;
155
+        } else {
156
+            return false;
157
+        }
158
+    }
159
+
160
+    @Override
161
+    public void setTopBarVisible(String screenInstanceId, boolean hidden, boolean animated) {
162
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
163
+            screenStacks[i].setScreenTopBarVisible(screenInstanceId, hidden, animated);
164
+        }
165
+    }
166
+
167
+    public void setBottomTabsVisible(boolean hidden, boolean animated) {
168
+        bottomTabs.setVisibility(hidden, animated);
169
+    }
170
+
171
+    @Override
172
+    public void setTitleBarTitle(String screenInstanceId, String title) {
173
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
174
+            screenStacks[i].setScreenTitleBarTitle(screenInstanceId, title);
175
+        }
176
+    }
177
+
178
+    @Override
179
+    public void setTitleBarSubtitle(String screenInstanceId, String subtitle) {
180
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
181
+            screenStacks[i].setScreenTitleBarSubtitle(screenInstanceId, subtitle);
182
+        }
183
+    }
184
+
185
+    @Override
186
+    public void setTitleBarRightButtons(String screenInstanceId, String navigatorEventId, List<TitleBarButtonParams> titleBarButtons) {
187
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
188
+            screenStacks[i].setScreenTitleBarRightButtons(screenInstanceId, navigatorEventId, titleBarButtons);
189
+        }
190
+    }
191
+
192
+    @Override
193
+    public void setTitleBarLeftButton(String screenInstanceId, String navigatorEventId, TitleBarLeftButtonParams titleBarLeftButtonParams) {
194
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
195
+            screenStacks[i].setScreenTitleBarLeftButton(screenInstanceId, navigatorEventId, titleBarLeftButtonParams);
196
+        }
197
+    }
198
+
199
+    @Override
200
+    public void setFab(String screenInstanceId, String navigatorEventId, FabParams fabParams) {
201
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
202
+            screenStacks[i].setFab(screenInstanceId, fabParams);
203
+        }
204
+    }
205
+
206
+    @Override
207
+    public void updateScreenStyle(String screenInstanceId, Bundle styleParams) {
208
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
209
+            screenStacks[i].updateScreenStyle(screenInstanceId, styleParams);
210
+        }
211
+    }
212
+
213
+    @Override
214
+    public void selectTopTabByTabIndex(String screenInstanceId, int index) {
215
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
216
+            screenStacks[i].selectTopTabByTabIndex(screenInstanceId, index);
217
+        }
218
+    }
219
+
220
+    @Override
221
+    public void selectTopTabByScreen(String screenInstanceId) {
222
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
223
+            screenStacks[i].selectTopTabByScreen(screenInstanceId);
224
+        }
225
+    }
226
+
227
+    @Override
228
+    public void toggleSideMenuVisible(boolean animated, Side side) {
229
+        if (sideMenu != null) {
230
+            sideMenu.toggleVisible(animated, side);
231
+        }
232
+    }
233
+
234
+    @Override
235
+    public void setSideMenuVisible(boolean animated, boolean visible, Side side) {
236
+        if (sideMenu != null) {
237
+            sideMenu.setVisible(visible, animated, side);
238
+        }
239
+    }
240
+
241
+    @Override
242
+    public void setSideMenuEnabled(boolean enabled, Side side) {
243
+        if (sideMenu != null) {
244
+            sideMenu.setDrawerLockMode(enabled ? DrawerLayout.LOCK_MODE_UNLOCKED : DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
245
+        }
246
+    }
247
+
248
+    @Override
249
+    public void showSnackbar(SnackbarParams params) {
250
+        final String eventId = getCurrentScreenStack().peek().getNavigatorEventId();
251
+        snackbarAndFabContainer.showSnackbar(eventId, params);
252
+    }
253
+
254
+    @Override
255
+    public void dismissSnackbar() {
256
+        snackbarAndFabContainer.dismissSnackbar();
257
+    }
258
+
259
+    @Override
260
+    public void showLightBox(LightBoxParams params) {
261
+        if (lightBox == null) {
262
+            lightBox = new LightBox(getActivity(), new Runnable() {
263
+                @Override
264
+                public void run() {
265
+                    lightBox = null;
266
+                }
267
+            }, params);
268
+            lightBox.show();
269
+        }
270
+    }
271
+
272
+    @Override
273
+    public void dismissLightBox() {
274
+        if (lightBox != null) {
275
+            lightBox.hide();
276
+            lightBox = null;
277
+        }
278
+    }
279
+
280
+    @Override
281
+    public void showSlidingOverlay(final SlidingOverlayParams params) {
282
+        slidingOverlaysQueue.add(new SlidingOverlay(this, params));
283
+    }
284
+
285
+    @Override
286
+    public void hideSlidingOverlay() {
287
+        slidingOverlaysQueue.remove();
288
+    }
289
+
290
+    @Override
291
+    public void onModalDismissed() {
292
+        EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
293
+    }
294
+
295
+    @Override
296
+    public boolean containsNavigator(String navigatorId) {
297
+        // Unused
298
+        return false;
299
+    }
300
+
301
+    @Override
302
+    public void showContextualMenu(String screenInstanceId, ContextualMenuParams params, Callback onButtonClicked) {
303
+        getCurrentScreenStack().peek().showContextualMenu(params, onButtonClicked);
304
+    }
305
+
306
+    @Override
307
+    public void dismissContextualMenu(String screenInstanceId) {
308
+        getCurrentScreenStack().peek().dismissContextualMenu();
309
+    }
310
+
311
+    @Override
312
+    public Screen getCurrentScreen() {
313
+        return getCurrentScreenStack().peek();
314
+    }
315
+
316
+    public void selectBottomTabByTabIndex(Integer index) {
317
+        bottomTabs.setCurrentItem(index);
318
+    }
319
+
320
+    public void selectBottomTabByNavigatorId(String navigatorId) {
321
+        bottomTabs.setCurrentItem(getScreenStackIndex(navigatorId));
322
+    }
323
+
324
+    private boolean hasBackgroundColor(StyleParams params) {
325
+        return params.screenBackgroundColor != null &&
326
+            params.screenBackgroundColor.hasColor();
327
+    }
328
+
329
+    private void setStyleFromScreen(StyleParams params) {
330
+        bottomTabs.setStyleFromScreen(params);
331
+        if (snackbarAndFabContainer != null && snackbarAndFabContainer.getLayoutParams() instanceof RelativeLayout.LayoutParams)
332
+            alignSnackbarContainerWithBottomTabs((LayoutParams) snackbarAndFabContainer.getLayoutParams(), params);
333
+        if (hasBackgroundColor(params)) {
334
+            asView().setBackgroundColor(params.screenBackgroundColor.getColor());
335
+        }
336
+    }
337
+
338
+    @Override
339
+    public void push(ScreenParams params) {
340
+        ScreenStack screenStack = getScreenStack(params.getNavigatorId());
341
+        screenStack.push(params, createScreenLayoutParams(params));
342
+        setStyleFromScreen(params.styleParams);
343
+        if (isCurrentStack(screenStack)) {
344
+            alignSnackbarContainerWithBottomTabs((LayoutParams) snackbarAndFabContainer.getLayoutParams(), params.styleParams);
345
+            EventBus.instance.post(new ScreenChangedEvent(params));
346
+        }
347
+    }
348
+
349
+    @Override
350
+    public void pop(final ScreenParams params) {
351
+        getCurrentScreenStack().pop(params.animateScreenTransitions, new ScreenStack.OnScreenPop() {
352
+            @Override
353
+            public void onScreenPopAnimationEnd() {
354
+                setBottomTabsStyleFromCurrentScreen();
355
+                alignSnackbarContainerWithBottomTabs((LayoutParams) snackbarAndFabContainer.getLayoutParams(), params.styleParams);
356
+                EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
357
+            }
358
+        });
359
+    }
360
+
361
+    @Override
362
+    public void popToRoot(final ScreenParams params) {
363
+        getCurrentScreenStack().popToRoot(params.animateScreenTransitions, new ScreenStack.OnScreenPop() {
364
+            @Override
365
+            public void onScreenPopAnimationEnd() {
366
+                setBottomTabsStyleFromCurrentScreen();
367
+                alignSnackbarContainerWithBottomTabs((LayoutParams) snackbarAndFabContainer.getLayoutParams(), params.styleParams);
368
+                EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
369
+            }
370
+        });
371
+    }
372
+
373
+    @Override
374
+    public void newStack(final ScreenParams params) {
375
+        ScreenStack screenStack = getScreenStack(params.getNavigatorId());
376
+        screenStack.newStack(params, createScreenLayoutParams(params));
377
+        if (isCurrentStack(screenStack)) {
378
+            setStyleFromScreen(params.styleParams);
379
+            alignSnackbarContainerWithBottomTabs((LayoutParams) snackbarAndFabContainer.getLayoutParams(), params.styleParams);
380
+            EventBus.instance.post(new ScreenChangedEvent(params));
381
+        }
382
+    }
383
+
384
+    private void alignSnackbarContainerWithBottomTabs(LayoutParams lp, StyleParams styleParams) {
385
+        if (styleParams.drawScreenAboveBottomTabs || !styleParams.bottomTabsHidden) {
386
+            lp.addRule(ABOVE, bottomTabs.getId());
387
+        } else {
388
+            ViewUtils.removeRuleCompat(lp, ABOVE);
389
+        }
390
+    }
391
+
392
+    @Override
393
+    public void destroy() {
394
+        snackbarAndFabContainer.destroy();
395
+        for (ScreenStack screenStack : screenStacks) {
396
+            screenStack.destroy();
397
+        }
398
+        if (sideMenu != null) {
399
+            sideMenu.destroy();
400
+        }
401
+        if (lightBox != null) {
402
+            lightBox.destroy();
403
+            lightBox = null;
404
+        }
405
+        slidingOverlaysQueue.destroy();
406
+    }
407
+
408
+    @Override
409
+    public boolean onTabSelected(int position, boolean wasSelected) {
410
+        if (wasSelected) {
411
+            sendTabReselectedEventToJs();
412
+            return false;
413
+        }
414
+
415
+        final int unselectedTabIndex = currentStackIndex;
416
+        hideCurrentStack();
417
+        showNewStack(position);
418
+        EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
419
+        sendTabSelectedEventToJs(position, unselectedTabIndex);
420
+        return true;
421
+    }
422
+
423
+    private void sendTabSelectedEventToJs(int selectedTabIndex, int unselectedTabIndex) {
424
+        String navigatorEventId = getCurrentScreenStack().peek().getNavigatorEventId();
425
+        WritableMap data = createTabSelectedEventData(selectedTabIndex, unselectedTabIndex);
426
+        NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("bottomTabSelected", navigatorEventId, data);
427
+
428
+        data = createTabSelectedEventData(selectedTabIndex, unselectedTabIndex);
429
+        NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("bottomTabSelected", data);
430
+    }
431
+
432
+    private WritableMap createTabSelectedEventData(int selectedTabIndex, int unselectedTabIndex) {
433
+        WritableMap data = Arguments.createMap();
434
+        data.putInt("selectedTabIndex", selectedTabIndex);
435
+        data.putInt("unselectedTabIndex", unselectedTabIndex);
436
+        return data;
437
+    }
438
+
439
+    private void sendTabReselectedEventToJs() {
440
+        WritableMap data = Arguments.createMap();
441
+        String navigatorEventId = getCurrentScreenStack().peek().getNavigatorEventId();
442
+        NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("bottomTabReselected", navigatorEventId, data);
443
+    }
444
+
445
+    private void showNewStack(int position) {
446
+        showStackAndUpdateStyle(screenStacks[position]);
447
+        currentStackIndex = position;
448
+    }
449
+
450
+    private void showStackAndUpdateStyle(ScreenStack newStack) {
451
+        newStack.show();
452
+        setStyleFromScreen(newStack.getCurrentScreenStyleParams());
453
+    }
454
+
455
+    private void hideCurrentStack() {
456
+        ScreenStack currentScreenStack = getCurrentScreenStack();
457
+        currentScreenStack.hide();
458
+    }
459
+
460
+    private ScreenStack getCurrentScreenStack() {
461
+        return screenStacks[currentStackIndex];
462
+    }
463
+
464
+    private
465
+    @NonNull
466
+    ScreenStack getScreenStack(String navigatorId) {
467
+        int index = getScreenStackIndex(navigatorId);
468
+        return screenStacks[index];
469
+    }
470
+
471
+    public void setBottomTabBadgeByIndex(Integer index, String badge) {
472
+        bottomTabs.setNotification(badge, index);
473
+    }
474
+
475
+    public void setBottomTabBadgeByNavigatorId(String navigatorId, String badge) {
476
+        bottomTabs.setNotification(badge, getScreenStackIndex(navigatorId));
477
+    }
478
+
479
+    public void setBottomTabButtonByIndex(Integer index, ScreenParams params) {
480
+        bottomTabs.setTabButton(params, index);
481
+    }
482
+
483
+    public void setBottomTabButtonByNavigatorId(String navigatorId, ScreenParams params) {
484
+        bottomTabs.setTabButton(params, getScreenStackIndex(navigatorId));
485
+    }
486
+
487
+    private int getScreenStackIndex(String navigatorId) throws ScreenStackNotFoundException {
488
+        for (int i = 0; i < screenStacks.length; i++) {
489
+            if (screenStacks[i].getNavigatorId().equals(navigatorId)) {
490
+                return i;
491
+            }
492
+        }
493
+        throw new ScreenStackNotFoundException("Stack " + navigatorId + " not found");
494
+    }
495
+
496
+    private class ScreenStackNotFoundException extends RuntimeException {
497
+        ScreenStackNotFoundException(String navigatorId) {
498
+            super(navigatorId);
499
+        }
500
+    }
501
+
502
+    private boolean isCurrentStack(ScreenStack screenStack) {
503
+        return getCurrentScreenStack() == screenStack;
504
+    }
505
+
506
+    private void setBottomTabsStyleFromCurrentScreen() {
507
+        setStyleFromScreen(getCurrentScreenStack().getCurrentScreenStyleParams());
508
+    }
509
+
510
+    @Override
511
+    public boolean onTitleBarBackButtonClick() {
512
+        if (getCurrentScreenStack().canPop()) {
513
+            getCurrentScreenStack().pop(true, new ScreenStack.OnScreenPop() {
514
+                @Override
515
+                public void onScreenPopAnimationEnd() {
516
+                    setBottomTabsStyleFromCurrentScreen();
517
+                    EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
518
+                }
519
+            });
520
+            return true;
521
+        }
522
+        return false;
523
+    }
524
+
525
+    @Override
526
+    public void onSideMenuButtonClick() {
527
+        final String navigatorEventId = getCurrentScreenStack().peek().getNavigatorEventId();
528
+        NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("sideMenu", navigatorEventId);
529
+        if (sideMenu != null) {
530
+            sideMenu.openDrawer(Side.Left);
531
+        }
532
+    }
533 533
 }