Browse Source

fixed containers

Daniel Zlotin 7 years ago
parent
commit
b33b3d20bf
15 changed files with 97 additions and 157 deletions
  1. 1
    1
      lib/android/app/src/main/java/com/reactnativenavigation/controllers/ActivityLifecycleDelegate.java
  2. 0
    34
      lib/android/app/src/main/java/com/reactnativenavigation/layout/ContainerStackLayout.java
  3. 0
    7
      lib/android/app/src/main/java/com/reactnativenavigation/layout/Layout.java
  4. 13
    15
      lib/android/app/src/main/java/com/reactnativenavigation/layout/LayoutFactory.java
  5. 2
    6
      lib/android/app/src/main/java/com/reactnativenavigation/layout/LayoutNode.java
  6. 0
    36
      lib/android/app/src/main/java/com/reactnativenavigation/layout/SideMenuLayout.java
  7. 3
    3
      lib/android/app/src/main/java/com/reactnativenavigation/layout/StackLayout.java
  8. 0
    4
      lib/android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/TooManyTabsException.java
  9. 4
    3
      lib/android/app/src/main/java/com/reactnativenavigation/layout/containers/BottomTabs.java
  10. 12
    25
      lib/android/app/src/main/java/com/reactnativenavigation/layout/containers/BottomTabsLayout.java
  11. 4
    3
      lib/android/app/src/main/java/com/reactnativenavigation/layout/containers/Container.java
  12. 31
    0
      lib/android/app/src/main/java/com/reactnativenavigation/layout/containers/ContainerStack.java
  13. 12
    0
      lib/android/app/src/main/java/com/reactnativenavigation/layout/containers/SideMenuLayout.java
  14. 13
    17
      lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationEventEmitter.java
  15. 2
    3
      lib/android/app/src/test/java/com/reactnativenavigation/layout/LayoutNodeTest.java

+ 1
- 1
lib/android/app/src/main/java/com/reactnativenavigation/controllers/ActivityLifecycleDelegate.java View File

60
 
60
 
61
 	private void emitAppLaunchedOnceIfNeeded() {
61
 	private void emitAppLaunchedOnceIfNeeded() {
62
 		if (appLaunchEmitted.compareAndSet(false, true)) {
62
 		if (appLaunchEmitted.compareAndSet(false, true)) {
63
-			NavigationEventEmitter.emit(reactInstanceManager.getCurrentReactContext()).appLaunched();
63
+			new NavigationEventEmitter(reactInstanceManager.getCurrentReactContext()).appLaunched();
64
 		}
64
 		}
65
 	}
65
 	}
66
 
66
 

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

1
-package com.reactnativenavigation.layout;
2
-
3
-import android.content.Context;
4
-import android.view.View;
5
-import android.widget.FrameLayout;
6
-
7
-import java.util.Stack;
8
-
9
-public class ContainerStackLayout extends FrameLayout implements StackLayout {
10
-
11
-	private Stack<View> backStack = new Stack<>();
12
-
13
-	public ContainerStackLayout(Context context) {
14
-		super(context);
15
-	}
16
-
17
-	@Override
18
-	public void push(View view) {
19
-		addView(view);
20
-		backStack.push(getChildAt(0));
21
-		removeView(getChildAt(0));
22
-	}
23
-
24
-	@Override
25
-	public void pop() {
26
-		addView(backStack.pop());
27
-		removeView(getChildAt(0));
28
-	}
29
-
30
-	@Override
31
-	public View asView() {
32
-		return this;
33
-	}
34
-}

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

1
-package com.reactnativenavigation.layout;
2
-
3
-import android.view.View;
4
-
5
-public interface Layout {
6
-	public View asView();
7
-}

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

7
 import android.view.ViewGroup.LayoutParams;
7
 import android.view.ViewGroup.LayoutParams;
8
 
8
 
9
 import com.facebook.react.ReactNativeHost;
9
 import com.facebook.react.ReactNativeHost;
10
-import com.reactnativenavigation.layout.bottomtabs.BottomTabs;
11
-import com.reactnativenavigation.layout.bottomtabs.BottomTabsLayout;
10
+import com.reactnativenavigation.layout.containers.BottomTabs;
11
+import com.reactnativenavigation.layout.containers.BottomTabsLayout;
12
+import com.reactnativenavigation.layout.containers.Container;
13
+import com.reactnativenavigation.layout.containers.ContainerStack;
14
+import com.reactnativenavigation.layout.containers.SideMenuLayout;
12
 import com.reactnativenavigation.utils.CompatUtils;
15
 import com.reactnativenavigation.utils.CompatUtils;
13
 
16
 
14
-import java.util.List;
15
-
16
 public class LayoutFactory {
17
 public class LayoutFactory {
17
 
18
 
18
 	private final Activity activity;
19
 	private final Activity activity;
26
 	public View create(LayoutNode node) {
27
 	public View create(LayoutNode node) {
27
 		switch (node.type) {
28
 		switch (node.type) {
28
 			case Container:
29
 			case Container:
29
-				return createContainerView(node);
30
+				return createContainer(node);
30
 			case ContainerStack:
31
 			case ContainerStack:
31
-				return createContainerStackView(node);
32
+				return createContainerStack(node);
32
 			case BottomTabs:
33
 			case BottomTabs:
33
 				return createBottomTabs(node);
34
 				return createBottomTabs(node);
34
 			case SideMenuRoot:
35
 			case SideMenuRoot:
74
 		return view;
75
 		return view;
75
 	}
76
 	}
76
 
77
 
77
-	private View createContainerView(LayoutNode node) {
78
+	private View createContainer(LayoutNode node) {
78
 		final String name = node.data.optString("name");
79
 		final String name = node.data.optString("name");
79
 		Container container = new Container(activity, reactNativeHost, node.id, name);
80
 		Container container = new Container(activity, reactNativeHost, node.id, name);
80
 		container.setId(CompatUtils.generateViewId());
81
 		container.setId(CompatUtils.generateViewId());
82
 
83
 
83
 	}
84
 	}
84
 
85
 
85
-	private View createContainerStackView(LayoutNode node) {
86
-		final ContainerStackLayout containerStack = new ContainerStackLayout(activity);
86
+	private View createContainerStack(LayoutNode node) {
87
+		final ContainerStack containerStack = new ContainerStack(activity);
87
 		containerStack.setId(CompatUtils.generateViewId());
88
 		containerStack.setId(CompatUtils.generateViewId());
88
-		addChildrenNodes(containerStack, node.children);
89
+		for (LayoutNode child : node.children) {
90
+			containerStack.addView(create(child));
91
+		}
89
 		return containerStack;
92
 		return containerStack;
90
 	}
93
 	}
91
 
94
 
98
 		return tabsContainer;
101
 		return tabsContainer;
99
 	}
102
 	}
100
 
103
 
101
-	private void addChildrenNodes(ContainerStackLayout containerStack, List<LayoutNode> children) {
102
-		for (LayoutNode child : children) {
103
-			containerStack.addView(create(child));
104
-		}
105
-	}
106
 }
104
 }

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

16
 		SideMenuRoot,
16
 		SideMenuRoot,
17
 		SideMenuCenter,
17
 		SideMenuCenter,
18
 		SideMenuLeft,
18
 		SideMenuLeft,
19
-		SideMenuRight;
20
-
21
-		public static Type fromString(String str) {
22
-			return valueOf(str);
23
-		}
19
+		SideMenuRight
24
 	}
20
 	}
25
 
21
 
26
 	@SuppressWarnings("unchecked")
22
 	@SuppressWarnings("unchecked")
27
 	public static LayoutNode parse(JSONObject layoutTree) {
23
 	public static LayoutNode parse(JSONObject layoutTree) {
28
 		String id = layoutTree.optString("id");
24
 		String id = layoutTree.optString("id");
29
-		LayoutNode.Type type = LayoutNode.Type.fromString(layoutTree.optString("type"));
25
+		LayoutNode.Type type = LayoutNode.Type.valueOf(layoutTree.optString("type"));
30
 		JSONObject data = parseData(layoutTree);
26
 		JSONObject data = parseData(layoutTree);
31
 		List<LayoutNode> children = parseChildren(layoutTree);
27
 		List<LayoutNode> children = parseChildren(layoutTree);
32
 		return new LayoutNode(id, type, data, children);
28
 		return new LayoutNode(id, type, data, children);

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

1
-package com.reactnativenavigation.layout;
2
-
3
-import android.content.Context;
4
-import android.support.v4.widget.DrawerLayout;
5
-import android.view.View;
6
-
7
-public class SideMenuLayout extends DrawerLayout implements StackLayout {
8
-	private StackLayout stackLayout;
9
-
10
-	public SideMenuLayout(Context context) {
11
-		super(context);
12
-	}
13
-
14
-	@Override
15
-	public void addView(View child) {
16
-		super.addView(child);
17
-		if (child instanceof StackLayout) {
18
-			stackLayout = (StackLayout) child;
19
-		}
20
-	}
21
-
22
-	@Override
23
-	public void push(View view) {
24
-		stackLayout.push(view);
25
-	}
26
-
27
-	@Override
28
-	public void pop() {
29
-		stackLayout.pop();
30
-	}
31
-
32
-	@Override
33
-	public View asView() {
34
-		return this;
35
-	}
36
-}

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

2
 
2
 
3
 import android.view.View;
3
 import android.view.View;
4
 
4
 
5
-public interface StackLayout extends Layout {
6
-	public void push(View view);
5
+public interface StackLayout {
6
+	void push(View view);
7
 
7
 
8
-	public void pop();
8
+	void pop();
9
 }
9
 }

+ 0
- 4
lib/android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/TooManyTabsException.java View File

1
-package com.reactnativenavigation.layout.bottomtabs;
2
-
3
-public class TooManyTabsException extends RuntimeException {
4
-}

lib/android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/BottomTabs.java → lib/android/app/src/main/java/com/reactnativenavigation/layout/containers/BottomTabs.java View File

1
-package com.reactnativenavigation.layout.bottomtabs;
1
+package com.reactnativenavigation.layout.containers;
2
 
2
 
3
 import android.graphics.Color;
3
 import android.graphics.Color;
4
 import android.support.annotation.NonNull;
4
 import android.support.annotation.NonNull;
8
 import android.widget.RelativeLayout;
8
 import android.widget.RelativeLayout;
9
 import android.widget.RelativeLayout.LayoutParams;
9
 import android.widget.RelativeLayout.LayoutParams;
10
 
10
 
11
-import static android.view.View.generateViewId;
11
+import com.reactnativenavigation.utils.CompatUtils;
12
+
12
 import static android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM;
13
 import static android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM;
13
 
14
 
14
 public class BottomTabs implements BottomNavigationView.OnNavigationItemSelectedListener {
15
 public class BottomTabs implements BottomNavigationView.OnNavigationItemSelectedListener {
50
 
51
 
51
 	private void createBottomNavigation(RelativeLayout parentLayout) {
52
 	private void createBottomNavigation(RelativeLayout parentLayout) {
52
 		bottomNavigationView = new BottomNavigationView(parentLayout.getContext());
53
 		bottomNavigationView = new BottomNavigationView(parentLayout.getContext());
53
-		bottomNavigationView.setId(generateViewId());
54
+		bottomNavigationView.setId(CompatUtils.generateViewId());
54
 		bottomNavigationView.setBackgroundColor(Color.DKGRAY);
55
 		bottomNavigationView.setBackgroundColor(Color.DKGRAY);
55
 		bottomNavigationView.setOnNavigationItemSelectedListener(this);
56
 		bottomNavigationView.setOnNavigationItemSelectedListener(this);
56
 	}
57
 	}

lib/android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/BottomTabsLayout.java → lib/android/app/src/main/java/com/reactnativenavigation/layout/containers/BottomTabsLayout.java View File

1
-package com.reactnativenavigation.layout.bottomtabs;
1
+package com.reactnativenavigation.layout.containers;
2
 
2
 
3
 import android.app.Activity;
3
 import android.app.Activity;
4
 import android.view.View;
4
 import android.view.View;
5
 import android.widget.RelativeLayout;
5
 import android.widget.RelativeLayout;
6
 
6
 
7
-import com.reactnativenavigation.layout.StackLayout;
8
-
9
 import java.util.ArrayList;
7
 import java.util.ArrayList;
10
 import java.util.List;
8
 import java.util.List;
11
 
9
 
12
-public class BottomTabsLayout extends RelativeLayout implements BottomTabs.BottomTabsSelectionListener, StackLayout {
10
+public class BottomTabsLayout extends RelativeLayout implements BottomTabs.BottomTabsSelectionListener {
11
+
12
+	public static class TooManyTabs extends RuntimeException {
13
+	}
14
+
13
 
15
 
14
-	private List<StackLayout> tabsContent;
16
+	private List<View> tabsContent;
15
 	private BottomTabs bottomTabs;
17
 	private BottomTabs bottomTabs;
16
 	private int currentTab;
18
 	private int currentTab;
17
 
19
 
21
 	}
23
 	}
22
 
24
 
23
 	public void addTabContent(String label, View tabContent) {
25
 	public void addTabContent(String label, View tabContent) {
24
-		if (tabsContent.size() == 5) {
25
-			throw new TooManyTabsException();
26
+		if (tabsContent.size() >= 5) {
27
+			throw new TooManyTabs();
26
 		}
28
 		}
27
 		bottomTabs.add(label);
29
 		bottomTabs.add(label);
28
 		attachTabContent(tabContent);
30
 		attachTabContent(tabContent);
29
-		tabsContent.add((StackLayout) tabContent);
31
+		tabsContent.add(tabContent);
30
 
32
 
31
 		if (tabsContent.size() > 1) {
33
 		if (tabsContent.size() > 1) {
32
 			tabContent.setVisibility(View.GONE);
34
 			tabContent.setVisibility(View.GONE);
55
 	}
57
 	}
56
 
58
 
57
 	private void showTab(int tabId) {
59
 	private void showTab(int tabId) {
58
-		tabsContent.get(tabId).asView().setVisibility(View.VISIBLE);
60
+		tabsContent.get(tabId).setVisibility(View.VISIBLE);
59
 	}
61
 	}
60
 
62
 
61
 	private void hideTab(int tabId) {
63
 	private void hideTab(int tabId) {
62
-		tabsContent.get(tabId).asView().setVisibility(View.GONE);
63
-	}
64
-
65
-	@Override
66
-	public void push(View view) {
67
-		tabsContent.get(currentTab).push(view);
68
-	}
69
-
70
-	@Override
71
-	public void pop() {
72
-		tabsContent.get(currentTab).pop();
73
-	}
74
-
75
-	@Override
76
-	public View asView() {
77
-		return this;
64
+		tabsContent.get(tabId).setVisibility(View.GONE);
78
 	}
65
 	}
79
 }
66
 }

lib/android/app/src/main/java/com/reactnativenavigation/layout/Container.java → lib/android/app/src/main/java/com/reactnativenavigation/layout/containers/Container.java View File

1
-package com.reactnativenavigation.layout;
1
+package com.reactnativenavigation.layout.containers;
2
 
2
 
3
 import android.app.Activity;
3
 import android.app.Activity;
4
 import android.os.Bundle;
4
 import android.os.Bundle;
7
 
7
 
8
 import com.facebook.react.ReactNativeHost;
8
 import com.facebook.react.ReactNativeHost;
9
 import com.facebook.react.ReactRootView;
9
 import com.facebook.react.ReactRootView;
10
+import com.facebook.react.bridge.ReactContext;
10
 import com.reactnativenavigation.NavigationApplication;
11
 import com.reactnativenavigation.NavigationApplication;
11
 import com.reactnativenavigation.react.NavigationEventEmitter;
12
 import com.reactnativenavigation.react.NavigationEventEmitter;
12
 
13
 
42
 	protected void onDetachedFromWindow() {
43
 	protected void onDetachedFromWindow() {
43
 		super.onDetachedFromWindow();
44
 		super.onDetachedFromWindow();
44
 		//TODO this is wrong
45
 		//TODO this is wrong
45
-		NavigationEventEmitter.emit(((NavigationApplication) getContext().getApplicationContext()).getReactNativeHost().getReactInstanceManager().getCurrentReactContext())
46
-				.containerStop(id);
46
+		ReactContext reactContext = ((NavigationApplication) getContext().getApplicationContext()).getReactNativeHost().getReactInstanceManager().getCurrentReactContext();
47
+		new NavigationEventEmitter(reactContext).containerStart(id);
47
 	}
48
 	}
48
 }
49
 }

+ 31
- 0
lib/android/app/src/main/java/com/reactnativenavigation/layout/containers/ContainerStack.java View File

1
+package com.reactnativenavigation.layout.containers;
2
+
3
+import android.content.Context;
4
+import android.view.View;
5
+import android.widget.FrameLayout;
6
+
7
+import com.reactnativenavigation.layout.StackLayout;
8
+
9
+import java.util.Stack;
10
+
11
+public class ContainerStack extends FrameLayout implements StackLayout {
12
+
13
+	private Stack<View> stack = new Stack<>();
14
+
15
+	public ContainerStack(Context context) {
16
+		super(context);
17
+	}
18
+
19
+	@Override
20
+	public void push(View view) {
21
+		addView(view);
22
+		stack.push(getChildAt(0));
23
+		removeView(getChildAt(0));
24
+	}
25
+
26
+	@Override
27
+	public void pop() {
28
+		addView(stack.pop());
29
+		removeView(getChildAt(0));
30
+	}
31
+}

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

1
+package com.reactnativenavigation.layout.containers;
2
+
3
+import android.content.Context;
4
+import android.support.v4.widget.DrawerLayout;
5
+
6
+public class SideMenuLayout extends DrawerLayout {
7
+
8
+	public SideMenuLayout(Context context) {
9
+		super(context);
10
+	}
11
+
12
+}

+ 13
- 17
lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationEventEmitter.java View File

11
 	private static final String containerStart = "RNN.containerStart";
11
 	private static final String containerStart = "RNN.containerStart";
12
 	private static final String containerStop = "RNN.containerStop";
12
 	private static final String containerStop = "RNN.containerStop";
13
 
13
 
14
-	public static NavigationEventEmitter emit(ReactContext context) {
15
-		return new NavigationEventEmitter(context);
16
-	}
17
-
18
 	private final RCTDeviceEventEmitter emitter;
14
 	private final RCTDeviceEventEmitter emitter;
19
 
15
 
20
-	private NavigationEventEmitter(ReactContext reactContext) {
16
+	public NavigationEventEmitter(ReactContext reactContext) {
21
 		this.emitter = reactContext.getJSModule(RCTDeviceEventEmitter.class);
17
 		this.emitter = reactContext.getJSModule(RCTDeviceEventEmitter.class);
22
 	}
18
 	}
23
 
19
 
25
 		emit(onAppLaunched);
21
 		emit(onAppLaunched);
26
 	}
22
 	}
27
 
23
 
28
-	private void emit(String eventName) {
29
-		emit(eventName, Arguments.createMap());
30
-	}
31
-
32
-	private void emit(String eventName, WritableMap data) {
33
-		emitter.emit(eventName, data);
34
-	}
35
-
36
-	private void emit(String eventName, String param) {
37
-		emitter.emit(eventName, param);
38
-	}
39
-
40
 	public void containerStop(String id) {
24
 	public void containerStop(String id) {
41
 		WritableMap data = Arguments.createMap();
25
 		WritableMap data = Arguments.createMap();
42
 		data.putString("id", id);
26
 		data.putString("id", id);
50
 //        emit(containerStart, data);
34
 //        emit(containerStart, data);
51
 		emit(containerStart, id);
35
 		emit(containerStart, id);
52
 	}
36
 	}
37
+
38
+	private void emit(String eventName) {
39
+		emit(eventName, Arguments.createMap());
40
+	}
41
+
42
+	private void emit(String eventName, WritableMap data) {
43
+		emitter.emit(eventName, data);
44
+	}
45
+
46
+	private void emit(String eventName, String param) {
47
+		emitter.emit(eventName, param);
48
+	}
53
 }
49
 }

+ 2
- 3
lib/android/app/src/test/java/com/reactnativenavigation/layout/LayoutNodeTest.java View File

1
 package com.reactnativenavigation.layout;
1
 package com.reactnativenavigation.layout;
2
 
2
 
3
 import com.reactnativenavigation.BaseTest;
3
 import com.reactnativenavigation.BaseTest;
4
-import com.reactnativenavigation.layout.LayoutNode;
5
 
4
 
6
 import org.json.JSONObject;
5
 import org.json.JSONObject;
7
 import org.junit.Test;
6
 import org.junit.Test;
20
 
19
 
21
 	@Test
20
 	@Test
22
 	public void parseType() throws Exception {
21
 	public void parseType() throws Exception {
23
-		assertThat(LayoutNode.Type.fromString("Container")).isEqualTo(LayoutNode.Type.Container);
22
+		assertThat(LayoutNode.Type.valueOf("Container")).isEqualTo(LayoutNode.Type.Container);
24
 	}
23
 	}
25
 
24
 
26
 	@Test(expected = RuntimeException.class)
25
 	@Test(expected = RuntimeException.class)
27
 	public void invalidType() throws Exception {
26
 	public void invalidType() throws Exception {
28
-		LayoutNode.Type.fromString("unknown");
27
+		LayoutNode.Type.valueOf("some type");
29
 	}
28
 	}
30
 
29
 
31
 	@Test
30
 	@Test