Selaa lähdekoodia

Initial TopTabs commit on Android (#2332)

Guy Carmeli 6 vuotta sitten
vanhempi
commit
7cf2b91f49
23 muutettua tiedostoa jossa 453 lisäystä ja 49 poistoa
  1. 0
    5
      lib/android/app/src/main/java/com/reactnativenavigation/anim/StackAnimator.java
  2. 24
    1
      lib/android/app/src/main/java/com/reactnativenavigation/parse/LayoutFactory.java
  3. 3
    1
      lib/android/app/src/main/java/com/reactnativenavigation/parse/LayoutNode.java
  4. 6
    2
      lib/android/app/src/main/java/com/reactnativenavigation/parse/NavigationOptions.java
  5. 17
    0
      lib/android/app/src/main/java/com/reactnativenavigation/parse/TopTabsOptions.java
  6. 22
    15
      lib/android/app/src/main/java/com/reactnativenavigation/presentation/OptionsPresenter.java
  7. 17
    1
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ContainerViewController.java
  8. 1
    2
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/SideMenuController.java
  9. 5
    5
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ViewController.java
  10. 25
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabController.java
  11. 32
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsAdapter.java
  12. 33
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsController.java
  13. 57
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsViewPager.java
  14. 3
    1
      lib/android/app/src/main/java/com/reactnativenavigation/views/TopBar.java
  15. 55
    0
      lib/android/app/src/main/java/com/reactnativenavigation/views/TopTab.java
  16. 19
    0
      lib/android/app/src/main/java/com/reactnativenavigation/views/TopTabCreator.java
  17. 11
    0
      lib/android/app/src/main/java/com/reactnativenavigation/views/TopTabs.java
  18. 1
    1
      lib/src/commands/Commands.js
  19. 32
    11
      lib/src/commands/LayoutTreeParser.js
  20. 32
    2
      lib/src/commands/LayoutTreeParser.test.js
  21. 3
    1
      lib/src/commands/LayoutTypes.js
  22. 22
    1
      lib/src/commands/SimpleLayouts.js
  23. 33
    0
      playground/src/containers/WelcomeScreen.js

+ 0
- 5
lib/android/app/src/main/java/com/reactnativenavigation/anim/StackAnimator.java Näytä tiedosto

@@ -4,19 +4,14 @@ import android.animation.Animator;
4 4
 import android.animation.AnimatorSet;
5 5
 import android.animation.ObjectAnimator;
6 6
 import android.animation.ValueAnimator;
7
-import android.app.Activity;
8 7
 import android.content.Context;
9 8
 import android.support.annotation.Nullable;
10 9
 import android.util.DisplayMetrics;
11
-import android.util.Log;
12 10
 import android.view.View;
13
-import android.view.ViewGroup;
14 11
 import android.view.WindowManager;
15 12
 import android.view.animation.AccelerateInterpolator;
16 13
 import android.view.animation.DecelerateInterpolator;
17
-import android.widget.FrameLayout;
18 14
 import android.widget.LinearLayout;
19
-import android.widget.RelativeLayout;
20 15
 
21 16
 import com.reactnativenavigation.views.TopBar;
22 17
 

+ 24
- 1
lib/android/app/src/main/java/com/reactnativenavigation/parse/LayoutFactory.java Näytä tiedosto

@@ -10,7 +10,10 @@ import com.reactnativenavigation.viewcontrollers.SideMenuController;
10 10
 import com.reactnativenavigation.viewcontrollers.StackController;
11 11
 import com.reactnativenavigation.viewcontrollers.ViewController;
12 12
 import com.reactnativenavigation.viewcontrollers.overlay.DialogViewController;
13
+import com.reactnativenavigation.viewcontrollers.toptabs.TopTabController;
14
+import com.reactnativenavigation.viewcontrollers.toptabs.TopTabsController;
13 15
 import com.reactnativenavigation.views.ContainerViewCreator;
16
+import com.reactnativenavigation.views.TopTabCreator;
14 17
 
15 18
 import java.util.ArrayList;
16 19
 import java.util.List;
@@ -45,12 +48,16 @@ public class LayoutFactory {
45 48
 				return createSideMenuRight(node);
46 49
 			case CustomDialog:
47 50
 				return createDialogContainer(node);
51
+            case TopTabsContainer:
52
+                return createTopTabsContainer(node);
53
+            case TopTab:
54
+                return createTopTabContainer(node);
48 55
 			default:
49 56
 				throw new IllegalArgumentException("Invalid node type: " + node.type);
50 57
 		}
51 58
 	}
52 59
 
53
-	private ViewController createSideMenuRoot(LayoutNode node) {
60
+    private ViewController createSideMenuRoot(LayoutNode node) {
54 61
 		SideMenuController sideMenuLayout = new SideMenuController(activity, node.id);
55 62
 		for (LayoutNode child : node.children) {
56 63
 			ViewController childLayout = create(child);
@@ -114,4 +121,20 @@ public class LayoutFactory {
114 121
 		ReactContainerViewCreator creator = new ReactContainerViewCreator(reactInstanceManager);
115 122
 		return new DialogViewController(activity, id, name, creator);
116 123
 	}
124
+
125
+    private ViewController createTopTabsContainer(LayoutNode node) {
126
+        final List<ViewController> tabs = new ArrayList<>();
127
+        for (LayoutNode child : node.children) {
128
+            tabs.add(create(child));
129
+        }
130
+        return new TopTabsController(activity, node.id, tabs);
131
+    }
132
+
133
+    private TopTabController createTopTabContainer(LayoutNode node) {
134
+        String name = node.data.optString("name");
135
+        return new TopTabController(activity,
136
+                node.id,
137
+                name,
138
+                new TopTabCreator(new ReactContainerViewCreator(reactInstanceManager)));
139
+    }
117 140
 }

+ 3
- 1
lib/android/app/src/main/java/com/reactnativenavigation/parse/LayoutNode.java Näytä tiedosto

@@ -14,7 +14,9 @@ public class LayoutNode {
14 14
 		SideMenuCenter,
15 15
 		SideMenuLeft,
16 16
 		SideMenuRight,
17
-		CustomDialog
17
+		CustomDialog,
18
+        TopTabsContainer,
19
+        TopTab
18 20
 	}
19 21
 
20 22
 	public final String id;

+ 6
- 2
lib/android/app/src/main/java/com/reactnativenavigation/parse/NavigationOptions.java Näytä tiedosto

@@ -30,21 +30,25 @@ public class NavigationOptions implements DEFAULT_VALUES {
30 30
 		if (json == null) return result;
31 31
 
32 32
 		result.topBarOptions = TopBarOptions.parse(json.optJSONObject("topBar"));
33
+		result.topTabsOptions = TopTabsOptions.parse(json.optJSONObject("topTabs"));
33 34
 		result.bottomTabsOptions = BottomTabsOptions.parse(json.optJSONObject("bottomTabs"));
34 35
 
35 36
 		return result.withDefaultOptions(defaultOptions);
36 37
 	}
37 38
 
38 39
 	public TopBarOptions topBarOptions = new TopBarOptions();
39
-	public BottomTabsOptions bottomTabsOptions = new BottomTabsOptions();
40
+    public TopTabsOptions topTabsOptions = new TopTabsOptions();
41
+    public BottomTabsOptions bottomTabsOptions = new BottomTabsOptions();
40 42
 
41 43
 	public void mergeWith(final NavigationOptions other) {
42 44
         topBarOptions.mergeWith(other.topBarOptions);
43
-		bottomTabsOptions.mergeWith(other.bottomTabsOptions);
45
+        topTabsOptions.mergeWith(other.topTabsOptions);
46
+        bottomTabsOptions.mergeWith(other.bottomTabsOptions);
44 47
 	}
45 48
 
46 49
     NavigationOptions withDefaultOptions(final NavigationOptions other) {
47 50
         topBarOptions.mergeWithDefault(other.topBarOptions);
51
+        topTabsOptions.mergeWithDefault(other.topTabsOptions);
48 52
         bottomTabsOptions.mergeWithDefault(other.bottomTabsOptions);
49 53
         return this;
50 54
     }

+ 17
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/TopTabsOptions.java Näytä tiedosto

@@ -0,0 +1,17 @@
1
+package com.reactnativenavigation.parse;
2
+
3
+import org.json.JSONObject;
4
+
5
+public class TopTabsOptions implements DEFAULT_VALUES {
6
+    public static TopTabsOptions parse(JSONObject topTabs) {
7
+        return new TopTabsOptions();
8
+    }
9
+
10
+    void mergeWith(TopTabsOptions topTabsOptions) {
11
+
12
+    }
13
+
14
+    void mergeWithDefault(TopTabsOptions topTabsOptions) {
15
+
16
+    }
17
+}

+ 22
- 15
lib/android/app/src/main/java/com/reactnativenavigation/presentation/OptionsPresenter.java Näytä tiedosto

@@ -4,6 +4,8 @@ import android.view.View;
4 4
 
5 5
 import com.reactnativenavigation.anim.StackAnimator;
6 6
 import com.reactnativenavigation.parse.NavigationOptions;
7
+import com.reactnativenavigation.parse.TopBarOptions;
8
+import com.reactnativenavigation.parse.TopTabsOptions;
7 9
 import com.reactnativenavigation.utils.TypefaceLoader;
8 10
 import com.reactnativenavigation.viewcontrollers.ContainerViewController;
9 11
 import com.reactnativenavigation.views.ContainerView;
@@ -20,24 +22,25 @@ public class OptionsPresenter {
20 22
 
21 23
 	public void applyOptions(NavigationOptions options) {
22 24
 		if (controller != null && controller.getTopBar() != null) {
23
-			controller.getTopBar().setTitle(options.topBarOptions.title);
24
-			controller.getTopBar().setBackgroundColor(options.topBarOptions.backgroundColor);
25
-			controller.getTopBar().setTitleTextColor(options.topBarOptions.textColor);
26
-			controller.getTopBar().setTitleFontSize(options.topBarOptions.textFontSize);
27
-			TypefaceLoader typefaceLoader = new TypefaceLoader();
28
-			controller.getTopBar().setTitleTypeface(typefaceLoader.getTypeFace(controller.getActivity(), options.topBarOptions.textFontFamily));
29
-			applyTopBarHiddenOptions(options);
25
+            applyTopBarOptions(options.topBarOptions);
26
+            applyTopTabsOptions(options.topTabsOptions);
30 27
 		}
31 28
 	}
32 29
 
33
-	private void applyTopBarHiddenOptions(NavigationOptions options) {
34
-		if (options.topBarOptions.hidden == NavigationOptions.BooleanOptions.True) {
35
-			hideTopBar(options.topBarOptions.animateHide);
36
-		}
37
-		if (options.topBarOptions.hidden == NavigationOptions.BooleanOptions.False) {
38
-			showTopBar(options.topBarOptions.animateHide);
39
-		}
40
-	}
30
+    private void applyTopBarOptions(TopBarOptions options) {
31
+        controller.setTitle(options.title);
32
+        controller.setBackgroundColor(options.backgroundColor);
33
+        controller.setTitleTextColor(options.textColor);
34
+        controller.setTitleFontSize(options.textFontSize);
35
+        TypefaceLoader typefaceLoader = new TypefaceLoader();
36
+        controller.getTopBar().setTitleTypeface(typefaceLoader.getTypeFace(controller.getActivity(), options.textFontFamily));
37
+        if (options.hidden == NavigationOptions.BooleanOptions.True) {
38
+            hideTopBar(options.animateHide);
39
+        }
40
+        if (options.hidden == NavigationOptions.BooleanOptions.False) {
41
+            showTopBar(options.animateHide);
42
+        }
43
+    }
41 44
 
42 45
 	private void showTopBar(NavigationOptions.BooleanOptions animated) {
43 46
 		if (controller.getTopBar().getVisibility() == View.VISIBLE) {
@@ -62,4 +65,8 @@ public class OptionsPresenter {
62 65
 			controller.getTopBar().setVisibility(View.GONE);
63 66
 		}
64 67
 	}
68
+
69
+    private void applyTopTabsOptions(TopTabsOptions topTabsOptions) {
70
+        // TODO: -guyca
71
+    }
65 72
 }

+ 17
- 1
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ContainerViewController.java Näytä tiedosto

@@ -12,7 +12,7 @@ import com.reactnativenavigation.views.ContainerView;
12 12
 
13 13
 public class ContainerViewController extends ViewController implements NavigationOptionsListener {
14 14
 
15
-	public interface ReactViewCreator {
15
+    public interface ReactViewCreator {
16 16
 
17 17
         IReactView create(Activity activity, String containerId, String containerName);
18 18
 	}
@@ -39,6 +39,22 @@ public class ContainerViewController extends ViewController implements Navigatio
39 39
 
40 40
 	private TopBar topBar;
41 41
 
42
+    public void setTitle(String title) {
43
+        topBar.setTitle(title);
44
+    }
45
+
46
+    public void setBackgroundColor(int backgroundColor) {
47
+        topBar.setBackgroundColor(backgroundColor);
48
+    }
49
+
50
+    public void setTitleTextColor(int textColor) {
51
+        topBar.setTitleTextColor(textColor);
52
+    }
53
+
54
+    public void setTitleFontSize(float textFontSize) {
55
+        topBar.setTitleFontSize(textFontSize);
56
+    }
57
+
42 58
 	public ContainerViewController(final Activity activity,
43 59
 								   final String id,
44 60
 								   final String containerName,

+ 1
- 2
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/SideMenuController.java Näytä tiedosto

@@ -26,8 +26,7 @@ public class SideMenuController extends ParentController {
26 26
 	@NonNull
27 27
 	@Override
28 28
 	protected ViewGroup createView() {
29
-		DrawerLayout root = new DrawerLayout(getActivity());
30
-		return root;
29
+        return new DrawerLayout(getActivity());
31 30
 	}
32 31
 
33 32
 	@NonNull

+ 5
- 5
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ViewController.java Näytä tiedosto

@@ -5,6 +5,7 @@ import android.support.annotation.NonNull;
5 5
 import android.support.annotation.Nullable;
6 6
 import android.view.View;
7 7
 import android.view.ViewGroup;
8
+import android.view.ViewManager;
8 9
 import android.view.ViewTreeObserver;
9 10
 
10 11
 import com.reactnativenavigation.utils.CompatUtils;
@@ -24,10 +25,9 @@ public abstract class ViewController implements ViewTreeObserver.OnGlobalLayoutL
24 25
 		this.id = id;
25 26
 	}
26 27
 
27
-	@NonNull
28 28
 	protected abstract View createView();
29 29
 
30
-	public void ensureViewIsCreated() {
30
+	void ensureViewIsCreated() {
31 31
 		getView();
32 32
 	}
33 33
 
@@ -40,7 +40,7 @@ public abstract class ViewController implements ViewTreeObserver.OnGlobalLayoutL
40 40
 	}
41 41
 
42 42
 	@Nullable
43
-	public StackController getParentStackController() {
43
+    StackController getParentStackController() {
44 44
 		return parentStackController;
45 45
 	}
46 46
 
@@ -62,7 +62,7 @@ public abstract class ViewController implements ViewTreeObserver.OnGlobalLayoutL
62 62
 		return id;
63 63
 	}
64 64
 
65
-	public boolean isSameId(final String id) {
65
+	boolean isSameId(final String id) {
66 66
 		return StringUtils.isEqual(this.id, id);
67 67
 	}
68 68
 
@@ -87,7 +87,7 @@ public abstract class ViewController implements ViewTreeObserver.OnGlobalLayoutL
87 87
 		if (view != null) {
88 88
 			view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
89 89
 			if (view.getParent() instanceof ViewGroup) {
90
-				((ViewGroup) view.getParent()).removeView(view);
90
+				((ViewManager) view.getParent()).removeView(view);
91 91
 			}
92 92
 			view = null;
93 93
 		}

+ 25
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabController.java Näytä tiedosto

@@ -0,0 +1,25 @@
1
+package com.reactnativenavigation.viewcontrollers.toptabs;
2
+
3
+import android.app.Activity;
4
+import android.support.annotation.NonNull;
5
+import android.view.ViewGroup;
6
+
7
+import com.reactnativenavigation.viewcontrollers.ViewController;
8
+import com.reactnativenavigation.views.TopTabCreator;
9
+
10
+public class TopTabController extends ViewController {
11
+    private String name;
12
+    private TopTabCreator topTabCreator;
13
+
14
+    public TopTabController(Activity activity, String id, String name, TopTabCreator topTabCreator) {
15
+        super(activity, id);
16
+        this.name = name;
17
+        this.topTabCreator = topTabCreator;
18
+    }
19
+
20
+    @NonNull
21
+    @Override
22
+    protected ViewGroup createView() {
23
+        return (ViewGroup) topTabCreator.create(getActivity(), getId(), name);
24
+    }
25
+}

+ 32
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsAdapter.java Näytä tiedosto

@@ -0,0 +1,32 @@
1
+package com.reactnativenavigation.viewcontrollers.toptabs;
2
+
3
+import android.support.v4.view.PagerAdapter;
4
+import android.view.View;
5
+import android.view.ViewGroup;
6
+
7
+import com.reactnativenavigation.viewcontrollers.ViewController;
8
+
9
+import java.util.List;
10
+
11
+public class TopTabsAdapter extends PagerAdapter {
12
+    private List<ViewController> tabs;
13
+
14
+    TopTabsAdapter(List<ViewController> tabs) {
15
+        this.tabs = tabs;
16
+    }
17
+
18
+    @Override
19
+    public int getCount() {
20
+        return tabs.size();
21
+    }
22
+
23
+    @Override
24
+    public boolean isViewFromObject(View view, Object object) {
25
+        return view == object;
26
+    }
27
+
28
+    @Override
29
+    public Object instantiateItem(ViewGroup container, int position) {
30
+        return tabs.get(position).getView();
31
+    }
32
+}

+ 33
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsController.java Näytä tiedosto

@@ -0,0 +1,33 @@
1
+package com.reactnativenavigation.viewcontrollers.toptabs;
2
+
3
+import android.app.Activity;
4
+import android.support.annotation.NonNull;
5
+import android.view.ViewGroup;
6
+
7
+import com.reactnativenavigation.viewcontrollers.ParentController;
8
+import com.reactnativenavigation.viewcontrollers.ViewController;
9
+
10
+import java.util.Collection;
11
+import java.util.List;
12
+
13
+public class TopTabsController extends ParentController {
14
+
15
+    private List<ViewController> tabs;
16
+
17
+    public TopTabsController(Activity activity, String id, List<ViewController> tabs) {
18
+        super(activity, id);
19
+        this.tabs = tabs;
20
+    }
21
+
22
+    @NonNull
23
+    @Override
24
+    protected ViewGroup createView() {
25
+        return new TopTabsViewPager(getActivity(), tabs);
26
+    }
27
+
28
+    @NonNull
29
+    @Override
30
+    public Collection<ViewController> getChildControllers() {
31
+        return tabs;
32
+    }
33
+}

+ 57
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsViewPager.java Näytä tiedosto

@@ -0,0 +1,57 @@
1
+package com.reactnativenavigation.viewcontrollers.toptabs;
2
+
3
+import android.content.Context;
4
+import android.support.v4.view.ViewPager;
5
+import android.view.View;
6
+import android.view.ViewGroup;
7
+
8
+import com.reactnativenavigation.viewcontrollers.ContainerViewController;
9
+import com.reactnativenavigation.viewcontrollers.ViewController;
10
+
11
+import java.util.List;
12
+
13
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
14
+
15
+public class TopTabsViewPager extends ViewPager implements ContainerViewController.IReactView {
16
+    private static final int OFFSCREEN_PAGE_LIMIT = 99;
17
+    private final List<ViewController> tabs;
18
+
19
+    public TopTabsViewPager(Context context, List<ViewController> tabs) {
20
+        super(context);
21
+        this.tabs = tabs;
22
+        init(tabs);
23
+    }
24
+
25
+    private void init(List<ViewController> tabs) {
26
+        setOffscreenPageLimit(OFFSCREEN_PAGE_LIMIT);
27
+        for (ViewController tab : tabs) {
28
+            addView(tab.getView(), new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
29
+        }
30
+        setAdapter(new TopTabsAdapter(tabs));
31
+    }
32
+
33
+    @Override
34
+    public boolean isReady() {
35
+        return false;
36
+    }
37
+
38
+    @Override
39
+    public View asView() {
40
+        return null;
41
+    }
42
+
43
+    @Override
44
+    public void destroy() {
45
+
46
+    }
47
+
48
+    @Override
49
+    public void sendContainerStart() {
50
+
51
+    }
52
+
53
+    @Override
54
+    public void sendContainerStop() {
55
+
56
+    }
57
+}

+ 3
- 1
lib/android/app/src/main/java/com/reactnativenavigation/views/TopBar.java Näytä tiedosto

@@ -12,11 +12,13 @@ import android.widget.TextView;
12 12
 
13 13
 public class TopBar extends AppBarLayout {
14 14
 	private final Toolbar titleBar;
15
+	private final TopTabs topTabs;
15 16
 
16 17
 	public TopBar(final Context context) {
17 18
 		super(context);
18 19
 		titleBar = new Toolbar(context);
19
-		addView(titleBar);
20
+        topTabs = new TopTabs(context);
21
+        addView(titleBar);
20 22
 	}
21 23
 
22 24
 	public void setTitle(String title) {

+ 55
- 0
lib/android/app/src/main/java/com/reactnativenavigation/views/TopTab.java Näytä tiedosto

@@ -0,0 +1,55 @@
1
+package com.reactnativenavigation.views;
2
+
3
+import android.content.Context;
4
+import android.view.View;
5
+import android.widget.FrameLayout;
6
+
7
+import com.reactnativenavigation.viewcontrollers.ContainerViewController.IReactView;
8
+
9
+public class TopTab extends FrameLayout implements IReactView {
10
+
11
+	private IReactView reactView;
12
+
13
+	public TopTab(Context context, IReactView reactView) {
14
+		super(context);
15
+		this.reactView = reactView;
16
+		initViews();
17
+	}
18
+
19
+	private void initViews() {
20
+		addView(reactView.asView());
21
+	}
22
+
23
+	public TopTab(Context context) {
24
+		super(context);
25
+	}
26
+
27
+	@Override
28
+	public boolean isReady() {
29
+		return reactView.isReady();
30
+	}
31
+
32
+	@Override
33
+	public View asView() {
34
+		return this;
35
+	}
36
+
37
+	@Override
38
+	public void destroy() {
39
+		reactView.destroy();
40
+	}
41
+
42
+	@Override
43
+	public void sendContainerStart() {
44
+		reactView.sendContainerStart();
45
+	}
46
+
47
+	@Override
48
+	public void sendContainerStop() {
49
+		reactView.sendContainerStop();
50
+	}
51
+
52
+	public IReactView getReactView() {
53
+		return reactView;
54
+	}
55
+}

+ 19
- 0
lib/android/app/src/main/java/com/reactnativenavigation/views/TopTabCreator.java Näytä tiedosto

@@ -0,0 +1,19 @@
1
+package com.reactnativenavigation.views;
2
+
3
+import android.app.Activity;
4
+
5
+import com.reactnativenavigation.viewcontrollers.ContainerViewController;
6
+
7
+public class TopTabCreator implements ContainerViewController.ReactViewCreator {
8
+
9
+	private ContainerViewController.ReactViewCreator creator;
10
+
11
+	public TopTabCreator(ContainerViewController.ReactViewCreator creator) {
12
+		this.creator = creator;
13
+	}
14
+
15
+	@Override
16
+	public ContainerViewController.IReactView create(Activity activity, String containerId, String containerName) {
17
+        return new TopTab(activity, creator.create(activity, containerId, containerName));
18
+	}
19
+}

+ 11
- 0
lib/android/app/src/main/java/com/reactnativenavigation/views/TopTabs.java Näytä tiedosto

@@ -0,0 +1,11 @@
1
+package com.reactnativenavigation.views;
2
+
3
+import android.content.Context;
4
+import android.support.design.widget.TabLayout;
5
+
6
+public class TopTabs extends TabLayout {
7
+
8
+    public TopTabs(Context context) {
9
+        super(context);
10
+    }
11
+}

+ 1
- 1
lib/src/commands/Commands.js Näytä tiedosto

@@ -44,7 +44,7 @@ class Commands {
44 44
 
45 45
   push(onContainerId, containerData) {
46 46
     const input = _.cloneDeep(containerData);
47
-    const layout = this.layoutTreeParser.createContainer(input);
47
+    const layout = this.layoutTreeParser.parseFromSimpleJSON(input);
48 48
     this.layoutTreeCrawler.crawl(layout);
49 49
     return this.nativeCommandsSender.push(onContainerId, layout);
50 50
   }

+ 32
- 11
lib/src/commands/LayoutTreeParser.js Näytä tiedosto

@@ -12,17 +12,15 @@ class LayoutTreeParser {
12 12
     if (simpleJsonApi.bottomTabs) {
13 13
       return this._createTabs(simpleJsonApi.bottomTabs);
14 14
     }
15
+    if (simpleJsonApi.topTabs) {
16
+      return this._createTopTabsContainer(simpleJsonApi.topTabs);
17
+    }
18
+    if (simpleJsonApi.name) {
19
+      return this._createContainer(simpleJsonApi);
20
+    }
15 21
     return this._createContainerStackWithContainerData(simpleJsonApi.container);
16 22
   }
17 23
 
18
-  createContainer(data) {
19
-    return {
20
-      type: LayoutTypes.Container,
21
-      data,
22
-      children: []
23
-    };
24
-  }
25
-
26 24
   createDialogContainer(data) {
27 25
     return {
28 26
       type: LayoutTypes.CustomDialog,
@@ -38,10 +36,25 @@ class LayoutTreeParser {
38 36
     };
39 37
   }
40 38
 
39
+  _createTopTabsContainer(topTabs) {
40
+    return {
41
+      type: LayoutTypes.TopTabsContainer,
42
+      children: _.map(topTabs, (t) => this._createTopTab(t.container))
43
+    };
44
+  }
45
+
46
+  _createTopTab(data) {
47
+    return {
48
+      type: LayoutTypes.TopTab,
49
+      data,
50
+      children: []
51
+    };
52
+  }
53
+
41 54
   _createContainerStackWithContainerData(containerData) {
42 55
     return {
43 56
       type: LayoutTypes.ContainerStack,
44
-      children: [this.createContainer(containerData)]
57
+      children: [this._createContainer(containerData)]
45 58
     };
46 59
   }
47 60
 
@@ -57,7 +70,7 @@ class LayoutTreeParser {
57 70
     if (layout.sideMenu.left) {
58 71
       children.push({
59 72
         type: LayoutTypes.SideMenuLeft,
60
-        children: [this.createContainer(layout.sideMenu.left.container)]
73
+        children: [this._createContainer(layout.sideMenu.left.container)]
61 74
       });
62 75
     }
63 76
     children.push({
@@ -69,11 +82,19 @@ class LayoutTreeParser {
69 82
     if (layout.sideMenu.right) {
70 83
       children.push({
71 84
         type: LayoutTypes.SideMenuRight,
72
-        children: [this.createContainer(layout.sideMenu.right.container)]
85
+        children: [this._createContainer(layout.sideMenu.right.container)]
73 86
       });
74 87
     }
75 88
     return children;
76 89
   }
90
+
91
+  _createContainer(data) {
92
+    return {
93
+      type: LayoutTypes.Container,
94
+      data,
95
+      children: []
96
+    };
97
+  }
77 98
 }
78 99
 
79 100
 module.exports = LayoutTreeParser;

+ 32
- 2
lib/src/commands/LayoutTreeParser.test.js Näytä tiedosto

@@ -285,15 +285,45 @@ describe('LayoutTreeParser', () => {
285 285
           ]
286 286
         });
287 287
     });
288
+
289
+    it('parses bottomTabs with side menus', () => {
290
+      expect(uut.parseFromSimpleJSON(SimpleLayouts.singleScreenWithTopTabs))
291
+        .toEqual({
292
+          type: 'TopTabsContainer',
293
+          children: [
294
+            {
295
+              type: 'TopTab',
296
+              data: {
297
+                name: 'navigation.playground.TextScreen'
298
+              },
299
+              children: []
300
+            },
301
+            {
302
+              type: 'TopTab',
303
+              data: {
304
+                name: 'navigation.playground.TextScreen'
305
+              },
306
+              children: []
307
+            },
308
+            {
309
+              type: 'TopTab',
310
+              data: {
311
+                name: 'navigation.playground.TextScreen'
312
+              },
313
+              children: []
314
+            }
315
+          ]
316
+        });
317
+    });
288 318
   });
289 319
 
290 320
   describe('createContainer', () => {
291 321
     it('creates container object with passed data', () => {
292
-      expect(uut.createContainer({ foo: 'bar' })).toEqual({ type: 'Container', data: { foo: 'bar' }, children: [] });
322
+      expect(uut._createContainer({ foo: 'bar' })).toEqual({ type: 'Container', data: { foo: 'bar' }, children: [] });
293 323
     });
294 324
   });
295 325
 
296
-  describe('createDialogCOntainer', () => {
326
+  describe('createDialogContainer', () => {
297 327
     it('creates dialog container object with passed data', () => {
298 328
       expect(uut.createDialogContainer({ foo: 'bar' })).toEqual({ type: 'CustomDialog', data: { foo: 'bar' }, children: [] });
299 329
     });

+ 3
- 1
lib/src/commands/LayoutTypes.js Näytä tiedosto

@@ -6,5 +6,7 @@ module.exports = {
6 6
   SideMenuCenter: 'SideMenuCenter',
7 7
   SideMenuLeft: 'SideMenuLeft',
8 8
   SideMenuRight: 'SideMenuRight',
9
-  CustomDialog: 'CustomDialog'
9
+  CustomDialog: 'CustomDialog',
10
+  TopTabsContainer: 'TopTabsContainer',
11
+  TopTab: 'TopTab'
10 12
 };

+ 22
- 1
lib/src/commands/SimpleLayouts.js Näytä tiedosto

@@ -111,6 +111,26 @@ const tabBasedWithBothSideMenus = {
111 111
   }
112 112
 };
113 113
 
114
+const singleScreenWithTopTabs = {
115
+  topTabs: [
116
+    {
117
+      container: {
118
+        name: 'navigation.playground.TextScreen'
119
+      }
120
+    },
121
+    {
122
+      container: {
123
+        name: 'navigation.playground.TextScreen'
124
+      }
125
+    },
126
+    {
127
+      container: {
128
+        name: 'navigation.playground.TextScreen'
129
+      }
130
+    }
131
+  ]
132
+};
133
+
114 134
 module.exports = {
115 135
   singleScreenApp,
116 136
   passProps,
@@ -119,5 +139,6 @@ module.exports = {
119 139
   singleWithSideMenu,
120 140
   singleWithRightSideMenu,
121 141
   singleWithBothMenus,
122
-  tabBasedWithBothSideMenus
142
+  tabBasedWithBothSideMenus,
143
+  singleScreenWithTopTabs
123 144
 };

+ 33
- 0
playground/src/containers/WelcomeScreen.js Näytä tiedosto

@@ -22,6 +22,7 @@ class WelcomeScreen extends Component {
22 22
     this.onClickPushOptionsScreen = this.onClickPushOptionsScreen.bind(this);
23 23
     this.onClickPushOrientationMenuScreen = this.onClickPushOrientationMenuScreen.bind(this);
24 24
     this.onClickBackHandler = this.onClickBackHandler.bind(this);
25
+    this.onClickPushTopTabsScreen = this.onClickPushTopTabsScreen.bind(this);
25 26
   }
26 27
 
27 28
   render() {
@@ -33,6 +34,7 @@ class WelcomeScreen extends Component {
33 34
         <Button title="Push Lifecycle Screen" testID={testIDs.PUSH_LIFECYCLE_BUTTON} onPress={this.onClickLifecycleScreen} />
34 35
         <Button title="Push" testID={testIDs.PUSH_BUTTON} onPress={this.onClickPush} />
35 36
         <Button title="Push Options Screen" testID={testIDs.PUSH_OPTIONS_BUTTON} onPress={this.onClickPushOptionsScreen} />
37
+        <Button title="Push TopTabs screen" testID={testIDs.PUSH_TOP_TABS_BUTTON} onPress={this.onClickPushTopTabsScreen} />
36 38
         <Button title="Back Handler" testID={testIDs.BACK_HANDLER_BUTTON} onPress={this.onClickBackHandler} />
37 39
         <Button title="Show Modal" testID={testIDs.SHOW_MODAL_BUTTON} onPress={this.onClickShowModal} />
38 40
         <Button title="Show Redbox" testID={testIDs.SHOW_REDBOX_BUTTON} onPress={this.onClickShowRedbox} />
@@ -145,6 +147,37 @@ class WelcomeScreen extends Component {
145 147
     });
146 148
   }
147 149
 
150
+  onClickPushTopTabsScreen() {
151
+    Navigation.push(this.props.containerId, {
152
+      topTabs: [
153
+        {
154
+          container: {
155
+            name: 'navigation.playground.TextScreen',
156
+            passProps: {
157
+              text: 'This is top tab 1'
158
+            }
159
+          }
160
+        },
161
+        {
162
+          container: {
163
+            name: 'navigation.playground.TextScreen',
164
+            passProps: {
165
+              text: 'This is top tab 2'
166
+            }
167
+          }
168
+        },
169
+        {
170
+          container: {
171
+            name: 'navigation.playground.TextScreen',
172
+            passProps: {
173
+              text: 'This is top tab 3'
174
+            }
175
+          }
176
+        }
177
+      ]
178
+    });
179
+  }
180
+
148 181
   onClickBackHandler() {
149 182
     Navigation.push(this.props.containerId, {
150 183
       name: 'navigation.playground.BackHandlerScreen'