Skip to content

Commit

Permalink
[Android] Add ability to start app with deep stack (wix#2761)
Browse files Browse the repository at this point in the history
For example, the following code will start a single screen app with two
screens pushed into the stack.

```js
Navigation.startSingleScreenApp({
    components: [
    {
      screen: 'example.Types',
      title: 'Navigation Types',
      overrideBackPress: true
    },
    {
      screen: 'example.Types.CustomButtonScreen',
      title: 'Custom Buttons'
    }
  ]
});
```
  • Loading branch information
guyca authored Feb 21, 2018
1 parent 3240f8e commit e0a6ff2
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ private void createAndAddScreens(int position) {
ScreenParams screenParams = params.tabParams.get(position);
ScreenStack newStack = new ScreenStack(getActivity(), getScreenStackParent(), screenParams.getNavigatorId(), this);
newStack.pushInitialScreen(screenParams, createScreenLayoutParams(screenParams));
for (ScreenParams screen : screenParams.screens) {
newStack.pushInitialScreen(screen, createScreenLayoutParams(screen));
}
screenStacks[position] = newStack;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,18 @@ private void createStack(RelativeLayout parent) {
stack = new ScreenStack(getActivity(), parent, screenParams.getNavigatorId(), this);
LayoutParams lp = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
pushInitialScreen(lp);
pushAdditionalScreens(lp);
stack.show(NavigationType.Push);
}

protected void pushInitialScreen(LayoutParams lp) {
stack.pushInitialScreen(screenParams, lp);
stack.show(NavigationType.Push);
}

private void pushAdditionalScreens(LayoutParams lp) {
for (ScreenParams screen : screenParams.screens) {
stack.pushInitialScreen(screen, lp);
}
}

private void sendScreenChangedEventAfterInitialPush() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.reactnativenavigation.params;

import java.util.Collections;
import java.util.List;

public class ScreenParams extends BaseScreenParams {
public String tabLabel;
public List<PageParams> topTabParams;
public List<String> sharedElementsTransitions;
public List<ScreenParams> screens = Collections.EMPTY_LIST; // used to init a stack with multiple screens

public boolean hasTopTabs() {
return topTabParams != null && !topTabParams.isEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public static ScreenParams parse(Bundle params) {
result.leftButton = ButtonParser.parseLeftButton(params);

result.topTabParams = parseTopTabs(params);
if (hasKey(params, "screens")) {
result.screens = parseScreens(params.getBundle("screens"));
}

if (hasKey(params, FRAGMENT_CREATOR_CLASS_NAME)) {
result.fragmentCreatorClassName = params.getString(FRAGMENT_CREATOR_CLASS_NAME);
Expand Down Expand Up @@ -105,4 +108,13 @@ public ScreenParams parse(Bundle screen) {
}
});
}

private static List<ScreenParams> parseScreens(Bundle screens) {
return new Parser().parseBundle(screens, new ParseStrategy<ScreenParams>() {
@Override
public ScreenParams parse(Bundle screen) {
return ScreenParamsParser.parse(screen);
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,14 @@ public void onDisplay() {
public void pushInitialScreen(ScreenParams initialScreenParams, LayoutParams params) {
Screen initialScreen = ScreenFactory.create(activity, initialScreenParams, leftButtonOnClickListener);
initialScreen.setVisibility(View.INVISIBLE);
removeCurrentScreen();
addScreen(initialScreen, params);
}

private void removeCurrentScreen() {
if (!stack.empty()) parent.removeView(peek());
}

public void push(final ScreenParams params, LayoutParams layoutParams, Promise onPushComplete) {
Screen nextScreen = ScreenFactory.create(activity, params, leftButtonOnClickListener);
final Screen previousScreen = stack.peek();
Expand Down
89 changes: 58 additions & 31 deletions src/deprecated/platformSpecificDeprecated.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,45 @@ const resolveAssetSource = require('react-native/Libraries/Image/resolveAssetSou
import * as newPlatformSpecific from './../platformSpecific';

async function startSingleScreenApp(params) {
const screen = params.screen;
if (!screen.screen) {
const components = params.components;
if (!params.screen && !components) {
console.error('startSingleScreenApp(params): screen must include a screen property');
return;
}

if (components) {
params.screen = createSingleScreen(components[0]);
components.shift();
params.screen.screens = components.map(createSingleScreen);
} else {
params.screen = createSingleScreen(params.screen);
}

params.sideMenu = convertDrawerParamsToSideMenuParams(params.drawer);
params.overrideBackPress = params.screen.overrideBackPress;
params.animateShow = convertAnimationType(params.animationType);
params.appStyle = convertStyleParams(params.appStyle);
if (params.appStyle) {
params.appStyle.orientation = getOrientation(params);
}

return await newPlatformSpecific.startApp(params);
}

function createSingleScreen(params) {
let screen = params;
addNavigatorParams(screen);
addNavigatorButtons(screen, params.drawer);
addNavigationStyleParams(screen);
screen.passProps = params.passProps;

/*
* adapt to new API
*/
adaptTopTabs(screen, screen.navigatorID);
screen.screenId = screen.screen;
params.screen = adaptNavigationStyleToScreenStyle(screen);
params.screen = adaptNavigationParams(screen);
params.appStyle = convertStyleParams(params.appStyle);
if (params.appStyle) {
params.appStyle.orientation = getOrientation(params);
}
params.sideMenu = convertDrawerParamsToSideMenuParams(params.drawer);
params.overrideBackPress = screen.overrideBackPress;
params.animateShow = convertAnimationType(params.animationType);

return await newPlatformSpecific.startApp(params);
screen = adaptNavigationStyleToScreenStyle(screen);
screen = adaptNavigationParams(screen);
return screen;
}

function getOrientation(params) {
Expand Down Expand Up @@ -297,23 +310,18 @@ async function startTabBasedApp(params) {
params.tabs = _.cloneDeep(params.tabs);

params.tabs.forEach(function(tab, idx) {
addNavigatorParams(tab, null, idx);
addNavigatorButtons(tab, params.drawer);
addNavigationStyleParams(tab);
addTabIcon(tab);
if (!tab.passProps) {
tab.passProps = params.passProps;
if (tab.components) {
const components = tab.components;
const screen = createBottomTabScreen(components[0], idx, params)
const {label, icon} = components[0];
components.shift();
console.log('guyca', `${JSON.stringify(components[0])}`);
screen.screens = components.map(c => createBottomTabScreen({...c, icon, label}, idx, params));

newTabs.push(screen);
} else {
newTabs.push(createBottomTabScreen(tab, idx, params));
}

adaptTopTabs(tab, tab.navigatorID);

tab.screenId = tab.screen;

let newtab = adaptNavigationStyleToScreenStyle(tab);
newtab = adaptNavigationParams(tab);
newtab.overrideBackPress = tab.overrideBackPress;
newtab.timestamp = Date.now();
newTabs.push(newtab);
});
params.tabs = newTabs;

Expand All @@ -327,6 +335,26 @@ async function startTabBasedApp(params) {
return await newPlatformSpecific.startApp(params);
}

function createBottomTabScreen(tab, idx, params) {
addNavigatorParams(tab, null, idx);
addNavigatorButtons(tab, params.drawer);
addNavigationStyleParams(tab);
addTabIcon(tab);
if (!tab.passProps) {
tab.passProps = params.passProps;
}

adaptTopTabs(tab, tab.navigatorID);

tab.screenId = tab.screen;

let newtab = adaptNavigationStyleToScreenStyle(tab);
newtab = adaptNavigationParams(tab);
newtab.overrideBackPress = tab.overrideBackPress;
newtab.timestamp = Date.now();
return newtab;
};

function addTabIcon(tab) {
if (tab.icon) {
const icon = resolveAssetSource(tab.icon);
Expand Down Expand Up @@ -553,7 +581,6 @@ function addNavigatorParams(screen, navigator = null, idx = '') {
}

function addNavigatorButtons(screen, sideMenuParams) {

const Screen = Navigation.getRegisteredScreen(screen.screen);
if (screen.navigatorButtons == null) {
screen.navigatorButtons = _.cloneDeep(Screen.navigatorButtons);
Expand Down

0 comments on commit e0a6ff2

Please sign in to comment.