Browse Source

trying to pop

Daniel Zlotin 7 years ago
parent
commit
00d30a511f

+ 1
- 1
AndroidE2E/app/src/androidTest/java/com/reactnativenavigation/e2e/androide2e/ScreenStackTest.java View File

@@ -25,7 +25,7 @@ public class ScreenStackTest extends BaseTest {
25 25
 		assertExists(By.text("Stack Position: 1"));
26 26
 		elementByText("PUSH").click();
27 27
 		assertExists(By.text("Stack Position: 2"));
28
-		elementByText("Pop Previous").click();
28
+		elementByText("POP PREVIOUS").click();
29 29
 		assertExists(By.text("Stack Position: 2"));
30 30
 		elementByText("Pop").click();
31 31
 		assertMainShown();

+ 1
- 1
e2e/app.test.js View File

@@ -50,7 +50,7 @@ describe('screen stack', () => {
50 50
 
51 51
   it('pop screen deep in the stack', async () => {
52 52
     await elementByLabel('Push').tap();
53
-    await expect(elementByLabel('Stack Position: 1')).toBeVisible();
53
+    await expect(elementByLabel('Stack Position: 1')).t\oBeVisible();
54 54
     await elementByLabel('Push').tap();
55 55
     await expect(elementByLabel('Stack Position: 2')).toBeVisible();
56 56
     await elementByLabel('Pop Previous').tap();

+ 1
- 0
lib/android/app/build.gradle View File

@@ -55,6 +55,7 @@ dependencies {
55 55
     compile 'com.facebook.react:react-native:+'
56 56
 
57 57
     // third party
58
+    compile 'com.bluelinelabs:conductor:2.1.1'
58 59
     compile 'com.aurelhubert:ahbottomnavigation:1.3.3'
59 60
     compile 'com.balysv.materialmenu:material-menu-toolbar:1.5.4'
60 61
 

+ 2
- 0
lib/android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java View File

@@ -4,6 +4,7 @@ import android.os.Bundle;
4 4
 import android.support.annotation.Nullable;
5 5
 import android.support.v7.app.AppCompatActivity;
6 6
 import android.view.View;
7
+import android.widget.FrameLayout;
7 8
 
8 9
 import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
9 10
 import com.reactnativenavigation.layout.Layout;
@@ -16,6 +17,7 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
16 17
 	@Override
17 18
 	protected void onCreate(@Nullable Bundle savedInstanceState) {
18 19
 		super.onCreate(savedInstanceState);
20
+		setContentView(new FrameLayout(this));
19 21
 		app().activityLifecycle.onActivityCreated(this);
20 22
 	}
21 23
 

+ 4
- 1
lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java View File

@@ -5,17 +5,20 @@ import android.app.Application;
5 5
 import com.facebook.react.ReactApplication;
6 6
 import com.facebook.react.ReactNativeHost;
7 7
 import com.reactnativenavigation.controllers.ActivityLifecycleDelegate;
8
+import com.reactnativenavigation.controllers.Store;
8 9
 import com.reactnativenavigation.react.NavigationReactNativeHost;
9 10
 
10 11
 public abstract class NavigationApplication extends Application implements ReactApplication {
11 12
 
13
+	private Store store;
12 14
 	private NavigationReactNativeHost reactNativeHost;
13 15
 	ActivityLifecycleDelegate activityLifecycle;
14 16
 
15 17
 	@Override
16 18
 	public void onCreate() {
17 19
 		super.onCreate();
18
-		reactNativeHost = new NavigationReactNativeHost(this, isDebug());
20
+		store = new Store();
21
+		reactNativeHost = new NavigationReactNativeHost(this, isDebug(), store);
19 22
 		activityLifecycle = new ActivityLifecycleDelegate(reactNativeHost.getReactInstanceManager(), isDebug());
20 23
 	}
21 24
 

+ 18
- 0
lib/android/app/src/main/java/com/reactnativenavigation/controllers/Store.java View File

@@ -0,0 +1,18 @@
1
+package com.reactnativenavigation.controllers;
2
+
3
+import com.reactnativenavigation.layout.Layout;
4
+
5
+import java.util.HashMap;
6
+import java.util.Map;
7
+
8
+public class Store {
9
+	private Map<String, Layout> layoutsById = new HashMap<>();
10
+
11
+	public void setLayout(String id, Layout layout) {
12
+		layoutsById.put(id, layout);
13
+	}
14
+
15
+	public Layout getLayout(String id) {
16
+		return layoutsById.get(id);
17
+	}
18
+}

+ 6
- 0
lib/android/app/src/main/java/com/reactnativenavigation/layout/Layout.java View File

@@ -2,7 +2,13 @@ package com.reactnativenavigation.layout;
2 2
 
3 3
 import android.view.View;
4 4
 
5
+import com.reactnativenavigation.layout.impl.StackLayout;
6
+
5 7
 public interface Layout {
8
+	void setParentStackLayout(StackLayout stackLayout);
9
+
10
+	StackLayout getParentStackLayout();
11
+
6 12
 	View getView();
7 13
 
8 14
 	void destroy();

+ 17
- 8
lib/android/app/src/main/java/com/reactnativenavigation/layout/LayoutFactory.java View File

@@ -3,6 +3,7 @@ package com.reactnativenavigation.layout;
3 3
 import android.app.Activity;
4 4
 
5 5
 import com.facebook.react.ReactInstanceManager;
6
+import com.reactnativenavigation.controllers.Store;
6 7
 import com.reactnativenavigation.layout.impl.BottomTabsLayout;
7 8
 import com.reactnativenavigation.layout.impl.RootLayout;
8 9
 import com.reactnativenavigation.layout.impl.SideMenuLayout;
@@ -12,13 +13,21 @@ public class LayoutFactory {
12 13
 
13 14
 	private final Activity activity;
14 15
 	private ReactInstanceManager reactInstanceManager;
16
+	private Store store;
15 17
 
16
-	public LayoutFactory(Activity activity, final ReactInstanceManager reactInstanceManager) {
18
+	public LayoutFactory(Activity activity, final ReactInstanceManager reactInstanceManager, final Store store) {
17 19
 		this.activity = activity;
18 20
 		this.reactInstanceManager = reactInstanceManager;
21
+		this.store = store;
19 22
 	}
20 23
 
21
-	public Layout create(LayoutNode node) {
24
+	public Layout createAndSaveToStore(LayoutNode node) {
25
+		Layout layout = createLayout(node);
26
+		store.setLayout(node.id, layout);
27
+		return layout;
28
+	}
29
+
30
+	private Layout createLayout(final LayoutNode node) {
22 31
 		switch (node.type) {
23 32
 			case Container:
24 33
 				return createContainer(node);
@@ -42,7 +51,7 @@ public class LayoutFactory {
42 51
 	private Layout createSideMenuRoot(LayoutNode node) {
43 52
 		SideMenuLayout sideMenuLayout = new SideMenuLayout(activity);
44 53
 		for (LayoutNode child : node.children) {
45
-			Layout childLayout = create(child);
54
+			Layout childLayout = createAndSaveToStore(child);
46 55
 			switch (child.type) {
47 56
 				case SideMenuCenter:
48 57
 					sideMenuLayout.addCenterLayout(childLayout);
@@ -61,15 +70,15 @@ public class LayoutFactory {
61 70
 	}
62 71
 
63 72
 	private Layout createSideMenuContent(LayoutNode node) {
64
-		return create(node.children.get(0));
73
+		return createAndSaveToStore(node.children.get(0));
65 74
 	}
66 75
 
67 76
 	private Layout createSideMenuLeft(LayoutNode node) {
68
-		return create(node.children.get(0));
77
+		return createAndSaveToStore(node.children.get(0));
69 78
 	}
70 79
 
71 80
 	private Layout createSideMenuRight(LayoutNode node) {
72
-		return create(node.children.get(0));
81
+		return createAndSaveToStore(node.children.get(0));
73 82
 	}
74 83
 
75 84
 	private Layout createContainer(LayoutNode node) {
@@ -79,7 +88,7 @@ public class LayoutFactory {
79 88
 	private Layout createContainerStack(LayoutNode node) {
80 89
 		final StackLayout layoutStack = new StackLayout(activity);
81 90
 		for (LayoutNode child : node.children) {
82
-			layoutStack.push(create(child));
91
+			layoutStack.push(createAndSaveToStore(child));
83 92
 		}
84 93
 		return layoutStack;
85 94
 	}
@@ -87,7 +96,7 @@ public class LayoutFactory {
87 96
 	private Layout createBottomTabs(LayoutNode node) {
88 97
 		final BottomTabsLayout tabsContainer = new BottomTabsLayout(activity);
89 98
 		for (int i = 0; i < node.children.size(); i++) {
90
-			final Layout tabLayout = create(node.children.get(i));
99
+			final Layout tabLayout = createAndSaveToStore(node.children.get(i));
91 100
 			tabsContainer.addTab("#" + i, tabLayout);
92 101
 		}
93 102
 		return tabsContainer;

+ 12
- 0
lib/android/app/src/main/java/com/reactnativenavigation/layout/impl/BottomTabsLayout.java View File

@@ -23,6 +23,8 @@ import static android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM;
23 23
 
24 24
 public class BottomTabsLayout implements Layout, BottomNavigationView.OnNavigationItemSelectedListener {
25 25
 
26
+	private StackLayout stackLayout;
27
+
26 28
 	public static class TooManyTabs extends RuntimeException {
27 29
 		//
28 30
 	}
@@ -87,4 +89,14 @@ public class BottomTabsLayout implements Layout, BottomNavigationView.OnNavigati
87 89
 	private void hideTab(int tabId) {
88 90
 		tabs.get(tabId).getView().setVisibility(View.GONE);
89 91
 	}
92
+
93
+	@Override
94
+	public void setParentStackLayout(final StackLayout stackLayout) {
95
+		this.stackLayout = stackLayout;
96
+	}
97
+
98
+	@Override
99
+	public StackLayout getParentStackLayout() {
100
+		return stackLayout;
101
+	}
90 102
 }

+ 10
- 0
lib/android/app/src/main/java/com/reactnativenavigation/layout/impl/RootLayout.java View File

@@ -18,6 +18,7 @@ public class RootLayout implements Layout, View.OnAttachStateChangeListener {
18 18
 	private final FrameLayout view;
19 19
 	private final ReactRootView reactRootView;
20 20
 	private final ReactInstanceManager reactInstanceManager;
21
+	private StackLayout parentStackLayout;
21 22
 
22 23
 	public RootLayout(Activity activity, String id, String name, final ReactInstanceManager reactInstanceManager) {
23 24
 		this.id = id;
@@ -67,4 +68,13 @@ public class RootLayout implements Layout, View.OnAttachStateChangeListener {
67 68
 	private void onStop() {
68 69
 		new NavigationEvent(reactInstanceManager.getCurrentReactContext()).containerStop(id);
69 70
 	}
71
+
72
+	public void setParentStackLayout(final StackLayout parentStackLayout) {
73
+		this.parentStackLayout = parentStackLayout;
74
+	}
75
+
76
+	@Override
77
+	public StackLayout getParentStackLayout() {
78
+		return parentStackLayout;
79
+	}
70 80
 }

+ 11
- 0
lib/android/app/src/main/java/com/reactnativenavigation/layout/impl/SideMenuLayout.java View File

@@ -14,6 +14,7 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
14 14
 public class SideMenuLayout implements Layout {
15 15
 
16 16
 	private DrawerLayout view;
17
+	private StackLayout stackLayout;
17 18
 
18 19
 	public SideMenuLayout(Context context) {
19 20
 		view = new DrawerLayout(context);
@@ -50,4 +51,14 @@ public class SideMenuLayout implements Layout {
50 51
 		View child = childLayout.getView();
51 52
 		view.addView(child);
52 53
 	}
54
+
55
+	@Override
56
+	public void setParentStackLayout(final StackLayout stackLayout) {
57
+		this.stackLayout = stackLayout;
58
+	}
59
+
60
+	@Override
61
+	public StackLayout getParentStackLayout() {
62
+		return stackLayout;
63
+	}
53 64
 }

+ 20
- 2
lib/android/app/src/main/java/com/reactnativenavigation/layout/impl/StackLayout.java View File

@@ -13,6 +13,7 @@ public class StackLayout implements Layout {
13 13
 
14 14
 	private final Stack<Layout> stack = new Stack<>();
15 15
 	private final FrameLayout view;
16
+	private StackLayout stackLayout;
16 17
 
17 18
 	public StackLayout(Context context) {
18 19
 		view = new FrameLayout(context);
@@ -20,6 +21,7 @@ public class StackLayout implements Layout {
20 21
 	}
21 22
 
22 23
 	public void push(Layout child) {
24
+		child.setParentStackLayout(this);
23 25
 		stack.push(child);
24 26
 		view.addView(child.getView());
25 27
 		if (stack.size() > 1) {
@@ -38,8 +40,14 @@ public class StackLayout implements Layout {
38 40
 		}
39 41
 	}
40 42
 
41
-	public void pop(String containerId) {
42
-
43
+	public void pop(Layout layout) {
44
+		if (stack.peek() == layout) {
45
+			pop();
46
+		} else {
47
+			stack.remove(layout);
48
+			view.removeView(layout.getView());
49
+			layout.destroy();
50
+		}
43 51
 	}
44 52
 
45 53
 	public boolean onBackPressed() {
@@ -60,4 +68,14 @@ public class StackLayout implements Layout {
60 68
 	public void destroy() {
61 69
 		//
62 70
 	}
71
+
72
+	@Override
73
+	public void setParentStackLayout(final StackLayout stackLayout) {
74
+		this.stackLayout = stackLayout;
75
+	}
76
+
77
+	@Override
78
+	public StackLayout getParentStackLayout() {
79
+		return stackLayout;
80
+	}
63 81
 }

+ 10
- 7
lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationModule.java View File

@@ -6,6 +6,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
6 6
 import com.facebook.react.bridge.ReactMethod;
7 7
 import com.facebook.react.bridge.ReadableMap;
8 8
 import com.reactnativenavigation.NavigationActivity;
9
+import com.reactnativenavigation.controllers.Store;
9 10
 import com.reactnativenavigation.layout.Layout;
10 11
 import com.reactnativenavigation.layout.LayoutFactory;
11 12
 import com.reactnativenavigation.layout.LayoutNode;
@@ -17,10 +18,12 @@ import com.reactnativenavigation.utils.UiThread;
17 18
 public class NavigationModule extends ReactContextBaseJavaModule {
18 19
 	private static final String NAME = "RNNBridgeModule";
19 20
 	private final ReactInstanceManager reactInstanceManager;
21
+	private Store store;
20 22
 
21
-	public NavigationModule(final ReactApplicationContext reactContext, final ReactInstanceManager reactInstanceManager) {
23
+	public NavigationModule(final ReactApplicationContext reactContext, final ReactInstanceManager reactInstanceManager, final Store store) {
22 24
 		super(reactContext);
23 25
 		this.reactInstanceManager = reactInstanceManager;
26
+		this.store = store;
24 27
 	}
25 28
 
26 29
 	@Override
@@ -34,8 +37,8 @@ public class NavigationModule extends ReactContextBaseJavaModule {
34 37
 			@Override
35 38
 			public void run() {
36 39
 				final LayoutNode layoutTree = LayoutNodeParser.parse(JSONParser.parse(rawLayoutTree));
37
-				LayoutFactory factory = new LayoutFactory(activity(), reactInstanceManager);
38
-				final Layout rootView = factory.create(layoutTree);
40
+				LayoutFactory factory = new LayoutFactory(activity(), reactInstanceManager, store);
41
+				final Layout rootView = factory.createAndSaveToStore(layoutTree);
39 42
 				activity().setContentView(rootView.getView());
40 43
 				activity().setLayout(rootView);
41 44
 			}
@@ -48,8 +51,8 @@ public class NavigationModule extends ReactContextBaseJavaModule {
48 51
 			@Override
49 52
 			public void run() {
50 53
 				final LayoutNode layoutTree = LayoutNodeParser.parse(JSONParser.parse(rawLayoutTree));
51
-				LayoutFactory factory = new LayoutFactory(activity(), reactInstanceManager);
52
-				final Layout rootView = factory.create(layoutTree);
54
+				LayoutFactory factory = new LayoutFactory(activity(), reactInstanceManager, store);
55
+				final Layout rootView = factory.createAndSaveToStore(layoutTree);
53 56
 				((StackLayout) activity().getLayout()).push(rootView);
54 57
 			}
55 58
 		});
@@ -60,8 +63,8 @@ public class NavigationModule extends ReactContextBaseJavaModule {
60 63
 		handle(new Runnable() {
61 64
 			@Override
62 65
 			public void run() {
63
-
64
-				((StackLayout) activity().getLayout()).pop();
66
+				Layout layout = store.getLayout(onContainerId);
67
+				layout.getParentStackLayout().pop(layout);
65 68
 			}
66 69
 		});
67 70
 	}

+ 5
- 2
lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationPackage.java View File

@@ -6,6 +6,7 @@ import com.facebook.react.bridge.JavaScriptModule;
6 6
 import com.facebook.react.bridge.NativeModule;
7 7
 import com.facebook.react.bridge.ReactApplicationContext;
8 8
 import com.facebook.react.uimanager.ViewManager;
9
+import com.reactnativenavigation.controllers.Store;
9 10
 
10 11
 import java.util.Arrays;
11 12
 import java.util.Collections;
@@ -14,15 +15,17 @@ import java.util.List;
14 15
 public class NavigationPackage implements ReactPackage {
15 16
 
16 17
 	private ReactNativeHost reactNativeHost;
18
+	private Store store;
17 19
 
18
-	public NavigationPackage(final ReactNativeHost reactNativeHost) {
20
+	public NavigationPackage(final ReactNativeHost reactNativeHost, final Store store) {
19 21
 		this.reactNativeHost = reactNativeHost;
22
+		this.store = store;
20 23
 	}
21 24
 
22 25
 	@Override
23 26
 	public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
24 27
 		return Arrays.<NativeModule>asList(
25
-				new NavigationModule(reactContext, reactNativeHost.getReactInstanceManager())
28
+				new NavigationModule(reactContext, reactNativeHost.getReactInstanceManager(), store)
26 29
 		);
27 30
 	}
28 31
 

+ 5
- 2
lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationReactNativeHost.java View File

@@ -5,6 +5,7 @@ import android.app.Application;
5 5
 import com.facebook.react.ReactNativeHost;
6 6
 import com.facebook.react.ReactPackage;
7 7
 import com.facebook.react.shell.MainReactPackage;
8
+import com.reactnativenavigation.controllers.Store;
8 9
 
9 10
 import java.util.Arrays;
10 11
 import java.util.List;
@@ -12,10 +13,12 @@ import java.util.List;
12 13
 public class NavigationReactNativeHost extends ReactNativeHost {
13 14
 
14 15
 	private final boolean isDebug;
16
+	private Store store;
15 17
 
16
-	public NavigationReactNativeHost(Application application, boolean isDebug) {
18
+	public NavigationReactNativeHost(Application application, boolean isDebug, final Store store) {
17 19
 		super(application);
18 20
 		this.isDebug = isDebug;
21
+		this.store = store;
19 22
 	}
20 23
 
21 24
 	@Override
@@ -27,7 +30,7 @@ public class NavigationReactNativeHost extends ReactNativeHost {
27 30
 	protected List<ReactPackage> getPackages() {
28 31
 		return Arrays.<ReactPackage>asList(
29 32
 				new MainReactPackage(),
30
-				new NavigationPackage(this)
33
+				new NavigationPackage(this, store)
31 34
 		);
32 35
 	}
33 36
 }

+ 1
- 0
playground/android/build.gradle View File

@@ -20,5 +20,6 @@ allprojects {
20 20
             // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
21 21
             url "$rootDir/../../node_modules/react-native/android"
22 22
         }
23
+        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
23 24
     }
24 25
 }