Browse Source

Initial BottomTabs implementation

Guy Carmeli 8 years ago
parent
commit
7f8f1fa29c

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

@@ -0,0 +1,160 @@
1
+package com.reactnativenavigation.layouts;
2
+
3
+import android.content.Context;
4
+import android.graphics.Color;
5
+import android.view.View;
6
+import android.widget.RelativeLayout;
7
+
8
+import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
9
+import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem;
10
+import com.reactnativenavigation.params.ActivityParams;
11
+import com.reactnativenavigation.params.ScreenParams;
12
+import com.reactnativenavigation.params.TitleBarButtonParams;
13
+import com.reactnativenavigation.params.TitleBarLeftButtonParams;
14
+import com.reactnativenavigation.screens.ScreenStack;
15
+import com.reactnativenavigation.views.BottomTabs;
16
+
17
+import java.util.ArrayList;
18
+import java.util.List;
19
+
20
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
21
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
22
+
23
+public class BottomTabsLayout extends RelativeLayout implements Layout, AHBottomNavigation.OnTabSelectedListener {
24
+
25
+    private ActivityParams params;
26
+    private BottomTabs bottomTabs;
27
+    private List<ScreenStack> screenStacks;
28
+    private int currentStack = 0;
29
+
30
+    public BottomTabsLayout(Context context, ActivityParams params) {
31
+        super(context);
32
+        this.params = params;
33
+        screenStacks = new ArrayList<>();
34
+        createLayout();
35
+    }
36
+
37
+    private void createLayout() {
38
+        createBottomTabs();
39
+        addBottomTabsToScreen();
40
+        addInitialScreen();
41
+    }
42
+
43
+    private void createBottomTabs() {
44
+        bottomTabs = new BottomTabs(getContext());
45
+        setBottomTabsStyle();
46
+        addTabs();
47
+    }
48
+
49
+    private void addBottomTabsToScreen() {
50
+        LayoutParams lp = new LayoutParams(MATCH_PARENT, WRAP_CONTENT);
51
+        lp.addRule(ALIGN_PARENT_BOTTOM);
52
+        addView(bottomTabs, lp);
53
+    }
54
+
55
+    private void addInitialScreen() {
56
+        addView(getFirstScreenStack());
57
+    }
58
+
59
+    private void setBottomTabsStyle() {
60
+//        bottomTabs.setForceTitlesDisplay(style.getBoolean(TAB_STYLE_INACTIVE_TITLES, DEFAULT_TAB_INACTIVE_TITLES));
61
+        bottomTabs.setForceTint(true);
62
+//        bottomTabs.setDefaultBackgroundColor(getColor(style, TAB_STYLE_BAR_BG_COLOR, DEFAULT_TAB_BAR_BG_COLOR));
63
+//        bottomTabs.setInactiveColor(getColor(style, TAB_STYLE_BUTTON_COLOR, DEFAULT_TAB_BUTTON_COLOR));
64
+//        bottomTabs.setAccentColor(getColor(style, TAB_STYLE_SELECTED_COLOR, DEFAULT_TAB_SELECTED_COLOR));
65
+    }
66
+
67
+    private void addTabs() {
68
+        for (ScreenParams screenParams : params.tabParams) {
69
+            ScreenStack stack = new ScreenStack(getContext(), screenParams);
70
+            screenStacks.add(stack);
71
+
72
+            AHBottomNavigationItem item = new AHBottomNavigationItem(screenParams.title, screenParams.tabIcon,
73
+                    Color.GRAY);
74
+            bottomTabs.addItem(item);
75
+            bottomTabs.setOnTabSelectedListener(this);
76
+        }
77
+    }
78
+
79
+    @Override
80
+    public View asView() {
81
+        return this;
82
+    }
83
+
84
+    @Override
85
+    public boolean onBackPressed() {
86
+        return false;
87
+    }
88
+
89
+    @Override
90
+    public void setTopBarVisible(String screenInstanceId, boolean hidden, boolean animated) {
91
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
92
+            screenStacks.get(i).setTopBarVisible(screenInstanceId, hidden, animated);
93
+        }
94
+    }
95
+
96
+    @Override
97
+    public void setTitleBarTitle(String screenInstanceId, String title) {
98
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
99
+            screenStacks.get(i).setTitleBarTitle(screenInstanceId, title);
100
+        }
101
+    }
102
+
103
+    @Override
104
+    public void setTitleBarRightButtons(String screenInstanceId, String navigatorEventId, List<TitleBarButtonParams> titleBarButtons) {
105
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
106
+            screenStacks.get(i).setTitleBarRightButtons(screenInstanceId, navigatorEventId, titleBarButtons);
107
+        }
108
+    }
109
+
110
+    @Override
111
+    public void setTitleBarLeftButton(String screenInstanceId, String navigatorEventId, TitleBarLeftButtonParams titleBarLeftButtonParams) {
112
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
113
+            screenStacks.get(i).setTitleBarLeftButton(screenInstanceId, navigatorEventId, titleBarLeftButtonParams);
114
+        }
115
+    }
116
+
117
+    @Override
118
+    public void push(ScreenParams screenParams) {
119
+        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
120
+//            screenStacks.get(i).push(screenParams);
121
+        }
122
+    }
123
+
124
+    @Override
125
+    public void pop(ScreenParams screenParams) {
126
+//        for (int i = 0; i < bottomTabs.getItemsCount(); i++) {
127
+//            screenStacks.get(i).pop();
128
+//        }
129
+    }
130
+
131
+    @Override
132
+    public void popToRoot(ScreenParams params) {
133
+
134
+    }
135
+
136
+    @Override
137
+    public void newStack(ScreenParams params) {
138
+
139
+    }
140
+
141
+    @Override
142
+    public void destroy() {
143
+
144
+    }
145
+
146
+    @Override
147
+    public void onTabSelected(int position, boolean wasSelected) {
148
+        removeView(getCurrentScreenStack());
149
+        addView(screenStacks.get(position), 0, new LayoutParams(MATCH_PARENT, MATCH_PARENT));
150
+        currentStack = position;
151
+    }
152
+
153
+    private ScreenStack getCurrentScreenStack() {
154
+        return screenStacks.get(currentStack);
155
+    }
156
+
157
+    private ScreenStack getFirstScreenStack() {
158
+        return screenStacks.get(0);
159
+    }
160
+}

+ 4
- 11
android/app/src/main/java/com/reactnativenavigation/layouts/LayoutFactory.java View File

@@ -8,7 +8,7 @@ public class LayoutFactory {
8 8
     public static Layout create(Activity activity, ActivityParams params) {
9 9
         switch (params.type) {
10 10
             case TabBased:
11
-                throw new UnsupportedOperationException("WHAT!? u crazy...");
11
+                return createBottomTabsScreenLayout(activity, params);
12 12
             case SingleScreen:
13 13
             default:
14 14
                 return createSingleScreenLayout(activity, params);
@@ -19,12 +19,9 @@ public class LayoutFactory {
19 19
         return new SingleScreenLayout(activity, params.screenParams);
20 20
     }
21 21
 
22
-//    private static void addBottomTabsIfNeeded(Activity activity, Params params, LinearLayout root) {
23
-//        if (params.bottomTabs.enabled) {
24
-//            AHBottomNavigation bottomTabs = createBottomTabs(activity);
25
-//            root.addView(bottomTabs, new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
26
-//        }
27
-//    }
22
+    private static Layout createBottomTabsScreenLayout(Activity activity, ActivityParams params) {
23
+        return new BottomTabsLayout(activity, params);
24
+    }
28 25
 //
29 26
 //    private static void addContentWithMenuIfNeeded(Activity activity, Params params, LinearLayout root, FrameLayout content) {
30 27
 //        if (params.sideMenu.enabled) {
@@ -35,10 +32,6 @@ public class LayoutFactory {
35 32
 //        }
36 33
 //    }
37 34
 //
38
-//    private static AHBottomNavigation createBottomTabs(Activity activity) {
39
-//        return new AHBottomNavigation(activity);
40
-//    }
41
-//
42 35
 //    private static LinearLayout createRoot(Activity activity) {
43 36
 //        LinearLayout root = new LinearLayout(activity);
44 37
 //        root.setOrientation(LinearLayout.VERTICAL);

+ 3
- 0
android/app/src/main/java/com/reactnativenavigation/params/ActivityParams.java View File

@@ -1,5 +1,7 @@
1 1
 package com.reactnativenavigation.params;
2 2
 
3
+import java.util.List;
4
+
3 5
 public class ActivityParams {
4 6
     public enum Type {
5 7
         SingleScreen, TabBased
@@ -7,4 +9,5 @@ public class ActivityParams {
7 9
 
8 10
     public Type type;
9 11
     public ScreenParams screenParams;
12
+    public List<ScreenParams> tabParams;
10 13
 }

+ 3
- 2
android/app/src/main/java/com/reactnativenavigation/params/ScreenParams.java View File

@@ -1,5 +1,6 @@
1 1
 package com.reactnativenavigation.params;
2 2
 
3
+import android.graphics.drawable.Drawable;
3 4
 import android.os.Bundle;
4 5
 
5 6
 import java.util.List;
@@ -12,8 +13,8 @@ public class ScreenParams {
12 13
     public String title;
13 14
     public ScreenStyleParams styleParams;
14 15
     public List<TopTabParams> topTabParams;
15
-    //    public String tabLabel; TODO when tabs are supported move to TabParams
16
-    //    public Drawable tabIcon;
16
+    public String tabLabel;
17
+    public Drawable tabIcon;
17 18
 
18 19
     // TODO navigationParams should be a terminated. destroyed. annihilated. disintegrated. banished from existence. + abolished, eradicated, exterminated...
19 20
     public String screenInstanceId;

+ 11
- 3
android/app/src/main/java/com/reactnativenavigation/params/parsers/ActivityParamsParser.java View File

@@ -4,11 +4,19 @@ import android.os.Bundle;
4 4
 
5 5
 import com.reactnativenavigation.params.ActivityParams;
6 6
 
7
-public class ActivityParamsParser {
7
+public class ActivityParamsParser extends Parser {
8 8
     public static ActivityParams parse(Bundle params) {
9 9
         ActivityParams result = new ActivityParams();
10
-        result.type = ActivityParams.Type.SingleScreen; //TODO tabs
11
-        result.screenParams = ScreenParamsParser.parse(params.getBundle("screen"));
10
+        if (hasKey(params, "screen")) {
11
+            result.type = ActivityParams.Type.SingleScreen;
12
+            result.screenParams = ScreenParamsParser.parse(params.getBundle("screen"));
13
+        }
14
+
15
+        if (hasKey(params, "tabs")) {
16
+            result.type = ActivityParams.Type.TabBased;
17
+            result.tabParams = ScreenParamsParser.parseTabs(params.getBundle("tabs"));
18
+        }
19
+
12 20
         return result;
13 21
     }
14 22
 }

+ 18
- 0
android/app/src/main/java/com/reactnativenavigation/params/parsers/ScreenParamsParser.java View File

@@ -3,6 +3,10 @@ package com.reactnativenavigation.params.parsers;
3 3
 import android.os.Bundle;
4 4
 
5 5
 import com.reactnativenavigation.params.ScreenParams;
6
+import com.reactnativenavigation.react.ImageLoader;
7
+
8
+import java.util.ArrayList;
9
+import java.util.List;
6 10
 
7 11
 public class ScreenParamsParser extends Parser {
8 12
     private static final String KEY_TITLE = "title";
@@ -37,6 +41,20 @@ public class ScreenParamsParser extends Parser {
37 41
         if (hasKey(params, TOP_TABS)) {
38 42
             result.topTabParams = TopTabParamsParser.parse(params.getBundle(TOP_TABS));
39 43
         }
44
+        if (hasKey(params, "label")) {
45
+            result.tabLabel = params.getString("label");
46
+        }
47
+        if (hasKey(params, "icon")) {
48
+            result.tabIcon = ImageLoader.loadImage(params.getString("icon"));
49
+        }
50
+        return result;
51
+    }
52
+
53
+    public static List<ScreenParams> parseTabs(Bundle params) {
54
+        List<ScreenParams> result = new ArrayList<>();
55
+        for (String key : params.keySet()) {
56
+            result.add(ScreenParamsParser.parse(params.getBundle(key)));
57
+        }
40 58
         return result;
41 59
     }
42 60
 }

+ 1
- 1
android/app/src/main/java/com/reactnativenavigation/screens/ScreenStack.java View File

@@ -92,7 +92,7 @@ public class ScreenStack extends FrameLayout implements TitleBarBackButtonListen
92 92
         }
93 93
     }
94 94
 
95
-    private Screen findScreenByScreenInstanceId(String screenInstanceId) {
95
+    public Screen findScreenByScreenInstanceId(String screenInstanceId) {
96 96
         if (stack.isEmpty()) {
97 97
             return null;
98 98
         }

+ 11
- 0
android/app/src/main/java/com/reactnativenavigation/views/BottomTabs.java View File

@@ -0,0 +1,11 @@
1
+package com.reactnativenavigation.views;
2
+
3
+import android.content.Context;
4
+
5
+import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
6
+
7
+public class BottomTabs extends AHBottomNavigation {
8
+    public BottomTabs(Context context) {
9
+        super(context);
10
+    }
11
+}

+ 20
- 15
src/deprecated/platformSpecificDeprecated.android.js View File

@@ -106,21 +106,26 @@ function adaptNavigationParams(screen) {
106 106
 }
107 107
 
108 108
 function startTabBasedApp(params) {
109
-  //if (!params.tabs) {
110
-  //  console.error('startTabBasedApp(params): params.tabs is required');
111
-  //  return;
112
-  //}
113
-  //
114
-  //params.tabs.forEach(function(tab, idx) {
115
-  //  addNavigatorParams(tab, null, idx);
116
-  //  addNavigatorButtons(tab);
117
-  //  addNavigationStyleParams(tab);
118
-  //  addTabIcon(tab);
119
-  //  tab.passProps = params.passProps;
120
-  //});
121
-  //
122
-  //const drawer = setupDrawer(params.drawer);
123
-  //RctActivity.startTabBasedApp(params.tabs, params.tabsStyle, drawer);
109
+  if (!params.tabs) {
110
+   console.error('startTabBasedApp(params): params.tabs is required');
111
+   return;
112
+  }
113
+
114
+  params.tabs.forEach(function(tab, idx) {
115
+    debugger;
116
+    addNavigatorParams(tab, null, idx);
117
+    addNavigatorButtons(tab);
118
+    addNavigationStyleParams(tab);
119
+    addTabIcon(tab);
120
+    tab.passProps = params.passProps;
121
+
122
+    tab.screenId = tab.screen;
123
+    tab.screen = adaptNavigationStyleToScreenStyle(tab);
124
+    tab.screen = adaptNavigationParams(tab);
125
+  });
126
+
127
+  // TODO: add drawer params
128
+  newPlatformSpecific.startApp(params);
124 129
 }
125 130
 
126 131
 function addTabIcon(tab) {

+ 0
- 8
src/platformSpecific.android.js View File

@@ -6,15 +6,7 @@ import Navigation from './Navigation';
6 6
 
7 7
 const NativeReactModule = NativeModules.NavigationReactModule;
8 8
 
9
-const resolveAssetSource = require('react-native/Libraries/Image/resolveAssetSource');
10
-
11 9
 function startApp(activityParams) {
12
-  const screen = activityParams.screen;
13
-  if (!screen.screenId) {
14
-    console.error('startApp(activityParams): screenId property must be supplied');
15
-    return;
16
-  }
17
-
18 10
   NativeReactModule.startApp(activityParams);
19 11
 }
20 12