Browse Source

Android right side menu (#547)

* Implement right SideMenu on Android

* Adapt toggleSideMenu and toggleSideMenuVisible to right SideMenu
Guy Carmeli 8 years ago
parent
commit
689ac03cf9
18 changed files with 161 additions and 92 deletions
  1. 5
    4
      android/app/src/main/java/com/reactnativenavigation/bridge/NavigationReactModule.java
  2. 6
    6
      android/app/src/main/java/com/reactnativenavigation/controllers/Modal.java
  3. 5
    4
      android/app/src/main/java/com/reactnativenavigation/controllers/NavigationActivity.java
  4. 5
    4
      android/app/src/main/java/com/reactnativenavigation/controllers/NavigationCommandsHandler.java
  5. 12
    9
      android/app/src/main/java/com/reactnativenavigation/layouts/BottomTabsLayout.java
  6. 3
    2
      android/app/src/main/java/com/reactnativenavigation/layouts/Layout.java
  7. 1
    1
      android/app/src/main/java/com/reactnativenavigation/layouts/LayoutFactory.java
  8. 4
    5
      android/app/src/main/java/com/reactnativenavigation/layouts/ModalScreenLayout.java
  9. 14
    10
      android/app/src/main/java/com/reactnativenavigation/layouts/SingleScreenLayout.java
  10. 2
    1
      android/app/src/main/java/com/reactnativenavigation/params/ActivityParams.java
  11. 3
    3
      android/app/src/main/java/com/reactnativenavigation/params/NavigationParams.java
  12. 3
    0
      android/app/src/main/java/com/reactnativenavigation/params/SideMenuParams.java
  13. 5
    1
      android/app/src/main/java/com/reactnativenavigation/params/parsers/ActivityParamsParser.java
  14. 14
    2
      android/app/src/main/java/com/reactnativenavigation/params/parsers/SideMenuParamsParser.java
  15. 52
    25
      android/app/src/main/java/com/reactnativenavigation/views/SideMenu.java
  16. 2
    2
      android/app/src/main/java/com/reactnativenavigation/views/utils/ViewMeasurer.java
  17. 16
    7
      src/deprecated/platformSpecificDeprecated.android.js
  18. 9
    6
      src/platformSpecific.android.js

+ 5
- 4
android/app/src/main/java/com/reactnativenavigation/bridge/NavigationReactModule.java View File

@@ -15,6 +15,7 @@ import com.reactnativenavigation.params.parsers.ContextualMenuParamsParser;
15 15
 import com.reactnativenavigation.params.parsers.SnackbarParamsParser;
16 16
 import com.reactnativenavigation.params.parsers.TitleBarButtonParamsParser;
17 17
 import com.reactnativenavigation.params.parsers.TitleBarLeftButtonParamsParser;
18
+import com.reactnativenavigation.views.SideMenu.Side;
18 19
 
19 20
 import java.util.List;
20 21
 
@@ -113,13 +114,13 @@ public class NavigationReactModule extends ReactContextBaseJavaModule {
113 114
     }
114 115
 
115 116
     @ReactMethod
116
-    public void toggleSideMenuVisible(boolean animated) {
117
-        NavigationCommandsHandler.toggleSideMenuVisible(animated);
117
+    public void toggleSideMenuVisible(boolean animated, String side) {
118
+        NavigationCommandsHandler.toggleSideMenuVisible(animated, Side.fromString(side));
118 119
     }
119 120
 
120 121
     @ReactMethod
121
-    public void setSideMenuVisible(boolean animated, boolean visible) {
122
-        NavigationCommandsHandler.setSideMenuVisible(animated, visible);
122
+    public void setSideMenuVisible(boolean animated, boolean visible, String side) {
123
+        NavigationCommandsHandler.setSideMenuVisible(animated, visible, Side.fromString(side));
123 124
     }
124 125
 
125 126
     @ReactMethod

+ 6
- 6
android/app/src/main/java/com/reactnativenavigation/controllers/Modal.java View File

@@ -29,15 +29,15 @@ public class Modal extends Dialog implements DialogInterface.OnDismissListener,
29 29
         layout.setTopBarVisible(screenInstanceId, hidden, animated);
30 30
     }
31 31
 
32
-    public void setTitleBarTitle(String screenInstanceId, String title) {
32
+    void setTitleBarTitle(String screenInstanceId, String title) {
33 33
         layout.setTitleBarTitle(screenInstanceId, title);
34 34
     }
35 35
 
36
-    public void setTitleBarSubtitle(String screenInstanceId, String subtitle) {
36
+    void setTitleBarSubtitle(String screenInstanceId, String subtitle) {
37 37
         layout.setTitleBarSubtitle(screenInstanceId, subtitle);
38 38
     }
39 39
 
40
-    public void setTitleBarRightButtons(String screenInstanceId, String navigatorEventId, List<TitleBarButtonParams> titleBarButtons) {
40
+    void setTitleBarRightButtons(String screenInstanceId, String navigatorEventId, List<TitleBarButtonParams> titleBarButtons) {
41 41
         layout.setTitleBarRightButtons(screenInstanceId, navigatorEventId, titleBarButtons);
42 42
     }
43 43
 
@@ -64,7 +64,7 @@ public class Modal extends Dialog implements DialogInterface.OnDismissListener,
64 64
     public void onSideMenuButtonClick() {
65 65
     }
66 66
 
67
-    public interface OnModalDismissedListener {
67
+    interface OnModalDismissedListener {
68 68
         void onModalDismissed(Modal modal);
69 69
     }
70 70
 
@@ -84,7 +84,7 @@ public class Modal extends Dialog implements DialogInterface.OnDismissListener,
84 84
         setCancelable(true);
85 85
         setOnDismissListener(this);
86 86
         requestWindowFeature(Window.FEATURE_NO_TITLE);
87
-        layout = new ModalScreenLayout(getActivity(), null, screenParams, this);
87
+        layout = new ModalScreenLayout(getActivity(), screenParams, this);
88 88
         getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
89 89
         setContentView(layout.asView());
90 90
     }
@@ -131,7 +131,7 @@ public class Modal extends Dialog implements DialogInterface.OnDismissListener,
131 131
         onModalDismissedListener.onModalDismissed(this);
132 132
     }
133 133
 
134
-    public void onModalDismissed() {
134
+    void onModalDismissed() {
135 135
         layout.onModalDismissed();
136 136
     }
137 137
 }

+ 5
- 4
android/app/src/main/java/com/reactnativenavigation/controllers/NavigationActivity.java View File

@@ -29,6 +29,7 @@ import com.reactnativenavigation.params.SnackbarParams;
29 29
 import com.reactnativenavigation.params.TitleBarButtonParams;
30 30
 import com.reactnativenavigation.params.TitleBarLeftButtonParams;
31 31
 import com.reactnativenavigation.react.JsDevReloadHandler;
32
+import com.reactnativenavigation.views.SideMenu.Side;
32 33
 
33 34
 import java.util.List;
34 35
 
@@ -253,12 +254,12 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
253 254
         modalController.setTitleBarLeftButton(screenInstanceId, navigatorEventId, titleBarLeftButton);
254 255
     }
255 256
 
256
-    public void toggleSideMenuVisible(boolean animated) {
257
-        layout.toggleSideMenuVisible(animated);
257
+    public void toggleSideMenuVisible(boolean animated, Side side) {
258
+        layout.toggleSideMenuVisible(animated, side);
258 259
     }
259 260
 
260
-    public void setSideMenuVisible(boolean animated, boolean visible) {
261
-        layout.setSideMenuVisible(animated, visible);
261
+    public void setSideMenuVisible(boolean animated, boolean visible, Side side) {
262
+        layout.setSideMenuVisible(animated, visible, side);
262 263
     }
263 264
 
264 265
     public void selectBottomTabByTabIndex(Integer index) {

+ 5
- 4
android/app/src/main/java/com/reactnativenavigation/controllers/NavigationCommandsHandler.java View File

@@ -13,6 +13,7 @@ import com.reactnativenavigation.params.TitleBarButtonParams;
13 13
 import com.reactnativenavigation.params.TitleBarLeftButtonParams;
14 14
 import com.reactnativenavigation.params.parsers.ActivityParamsParser;
15 15
 import com.reactnativenavigation.params.parsers.ScreenParamsParser;
16
+import com.reactnativenavigation.views.SideMenu.Side;
16 17
 
17 18
 import java.util.List;
18 19
 
@@ -237,7 +238,7 @@ public class NavigationCommandsHandler {
237 238
         });
238 239
     }
239 240
 
240
-    public static void toggleSideMenuVisible(final boolean animated) {
241
+    public static void toggleSideMenuVisible(final boolean animated, final Side side) {
241 242
         final NavigationActivity currentActivity = NavigationActivity.currentActivity;
242 243
         if (currentActivity == null) {
243 244
             return;
@@ -246,12 +247,12 @@ public class NavigationCommandsHandler {
246 247
         NavigationApplication.instance.runOnMainThread(new Runnable() {
247 248
             @Override
248 249
             public void run() {
249
-                currentActivity.toggleSideMenuVisible(animated);
250
+                currentActivity.toggleSideMenuVisible(animated, side);
250 251
             }
251 252
         });
252 253
     }
253 254
 
254
-    public static void setSideMenuVisible(final boolean animated, final boolean visible) {
255
+    public static void setSideMenuVisible(final boolean animated, final boolean visible, final Side side) {
255 256
         final NavigationActivity currentActivity = NavigationActivity.currentActivity;
256 257
         if (currentActivity == null) {
257 258
             return;
@@ -260,7 +261,7 @@ public class NavigationCommandsHandler {
260 261
         NavigationApplication.instance.runOnMainThread(new Runnable() {
261 262
             @Override
262 263
             public void run() {
263
-                currentActivity.setSideMenuVisible(animated, visible);
264
+                currentActivity.setSideMenuVisible(animated, visible, side);
264 265
             }
265 266
         });
266 267
     }

+ 12
- 9
android/app/src/main/java/com/reactnativenavigation/layouts/BottomTabsLayout.java View File

@@ -21,6 +21,7 @@ import com.reactnativenavigation.params.TitleBarLeftButtonParams;
21 21
 import com.reactnativenavigation.screens.ScreenStack;
22 22
 import com.reactnativenavigation.views.BottomTabs;
23 23
 import com.reactnativenavigation.views.SideMenu;
24
+import com.reactnativenavigation.views.SideMenu.Side;
24 25
 import com.reactnativenavigation.views.SnackbarAndFabContainer;
25 26
 
26 27
 import java.util.List;
@@ -35,7 +36,8 @@ public class BottomTabsLayout extends RelativeLayout implements Layout, AHBottom
35 36
     private SnackbarAndFabContainer snackbarAndFabContainer;
36 37
     private BottomTabs bottomTabs;
37 38
     private ScreenStack[] screenStacks;
38
-    private final SideMenuParams sideMenuParams;
39
+    private final SideMenuParams leftSideMenuParams;
40
+    private final SideMenuParams rightSideMenuParams;
39 41
     private @Nullable SideMenu sideMenu;
40 42
     private int currentStackIndex = 0;
41 43
 
@@ -43,7 +45,8 @@ public class BottomTabsLayout extends RelativeLayout implements Layout, AHBottom
43 45
         super(activity);
44 46
         this.activity = activity;
45 47
         this.params = params;
46
-        this.sideMenuParams = params.sideMenuParams;
48
+        leftSideMenuParams = params.leftSideMenuParams;
49
+        rightSideMenuParams = params.rightSideMenuParams;
47 50
         screenStacks = new ScreenStack[params.tabParams.size()];
48 51
         createLayout();
49 52
     }
@@ -58,10 +61,10 @@ public class BottomTabsLayout extends RelativeLayout implements Layout, AHBottom
58 61
     }
59 62
 
60 63
     private void createSideMenu() {
61
-        if (sideMenuParams == null) {
64
+        if (leftSideMenuParams == null && rightSideMenuParams == null) {
62 65
             return;
63 66
         }
64
-        sideMenu = new SideMenu(getContext(), sideMenuParams);
67
+        sideMenu = new SideMenu(getContext(), leftSideMenuParams, rightSideMenuParams);
65 68
         RelativeLayout.LayoutParams lp = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
66 69
         addView(sideMenu, lp);
67 70
     }
@@ -176,16 +179,16 @@ public class BottomTabsLayout extends RelativeLayout implements Layout, AHBottom
176 179
     }
177 180
 
178 181
     @Override
179
-    public void toggleSideMenuVisible(boolean animated) {
182
+    public void toggleSideMenuVisible(boolean animated, Side side) {
180 183
         if (sideMenu != null) {
181
-            sideMenu.toggleVisible(animated);
184
+            sideMenu.toggleVisible(animated, side);
182 185
         }
183 186
     }
184 187
 
185 188
     @Override
186
-    public void setSideMenuVisible(boolean animated, boolean visible) {
189
+    public void setSideMenuVisible(boolean animated, boolean visible, Side side) {
187 190
         if (sideMenu != null) {
188
-            sideMenu.setVisible(visible, animated);
191
+            sideMenu.setVisible(visible, animated, side);
189 192
         }
190 193
     }
191 194
 
@@ -363,7 +366,7 @@ public class BottomTabsLayout extends RelativeLayout implements Layout, AHBottom
363 366
     @Override
364 367
     public void onSideMenuButtonClick() {
365 368
         if (sideMenu != null) {
366
-            sideMenu.openDrawer();
369
+            sideMenu.openDrawer(Side.Left);
367 370
         } else {
368 371
             final String navigatorEventId = getCurrentScreenStack().peek().getNavigatorEventId();
369 372
             NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("sideMenu", navigatorEventId);

+ 3
- 2
android/app/src/main/java/com/reactnativenavigation/layouts/Layout.java View File

@@ -7,6 +7,7 @@ import com.reactnativenavigation.params.ContextualMenuParams;
7 7
 import com.reactnativenavigation.params.SnackbarParams;
8 8
 import com.reactnativenavigation.params.TitleBarButtonParams;
9 9
 import com.reactnativenavigation.params.TitleBarLeftButtonParams;
10
+import com.reactnativenavigation.views.SideMenu.Side;
10 11
 
11 12
 import java.util.List;
12 13
 
@@ -25,9 +26,9 @@ public interface Layout extends ScreenStackContainer {
25 26
 
26 27
     void setTitleBarLeftButton(String screenInstanceId, String navigatorEventId, TitleBarLeftButtonParams titleBarLeftButtonParams);
27 28
 
28
-    void toggleSideMenuVisible(boolean animated);
29
+    void toggleSideMenuVisible(boolean animated, Side side);
29 30
 
30
-    void setSideMenuVisible(boolean animated, boolean visible);
31
+    void setSideMenuVisible(boolean animated, boolean visible, Side side);
31 32
 
32 33
     void showSnackbar(SnackbarParams params);
33 34
 

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

@@ -17,7 +17,7 @@ public class LayoutFactory {
17 17
     }
18 18
 
19 19
     private static Layout createSingleScreenLayout(AppCompatActivity activity, ActivityParams params) {
20
-        return new SingleScreenLayout(activity, params.sideMenuParams, params.screenParams);
20
+        return new SingleScreenLayout(activity, params.leftSideMenuParams, params.rightSideMenuParams, params.screenParams);
21 21
     }
22 22
 
23 23
     private static Layout createBottomTabsScreenLayout(AppCompatActivity activity, ActivityParams params) {

+ 4
- 5
android/app/src/main/java/com/reactnativenavigation/layouts/ModalScreenLayout.java View File

@@ -1,17 +1,16 @@
1 1
 package com.reactnativenavigation.layouts;
2 2
 
3
-import android.support.annotation.Nullable;
4 3
 import android.support.v7.app.AppCompatActivity;
5 4
 
6 5
 import com.reactnativenavigation.params.ScreenParams;
7
-import com.reactnativenavigation.params.SideMenuParams;
8 6
 import com.reactnativenavigation.views.LeftButtonOnClickListener;
9 7
 
10 8
 public class ModalScreenLayout extends SingleScreenLayout {
11 9
 
12
-    public ModalScreenLayout(AppCompatActivity activity, @Nullable SideMenuParams sideMenuParams,
13
-                             ScreenParams screenParams, LeftButtonOnClickListener leftButtonOnClickListener) {
14
-        super(activity, sideMenuParams, screenParams);
10
+    public ModalScreenLayout(AppCompatActivity activity,
11
+                             ScreenParams screenParams,
12
+                             LeftButtonOnClickListener leftButtonOnClickListener) {
13
+        super(activity, null, null, screenParams);
15 14
         this.leftButtonOnClickListener = leftButtonOnClickListener;
16 15
     }
17 16
 

+ 14
- 10
android/app/src/main/java/com/reactnativenavigation/layouts/SingleScreenLayout.java View File

@@ -18,6 +18,7 @@ import com.reactnativenavigation.params.TitleBarLeftButtonParams;
18 18
 import com.reactnativenavigation.screens.ScreenStack;
19 19
 import com.reactnativenavigation.views.LeftButtonOnClickListener;
20 20
 import com.reactnativenavigation.views.SideMenu;
21
+import com.reactnativenavigation.views.SideMenu.Side;
21 22
 import com.reactnativenavigation.views.SnackbarAndFabContainer;
22 23
 
23 24
 import java.util.List;
@@ -28,22 +29,25 @@ public class SingleScreenLayout extends RelativeLayout implements Layout {
28 29
 
29 30
     private final AppCompatActivity activity;
30 31
     protected final ScreenParams screenParams;
31
-    private final SideMenuParams sideMenuParams;
32
+    private final SideMenuParams leftSideMenuParams;
33
+    private final SideMenuParams rightSideMenuParams;
32 34
     protected ScreenStack stack;
33 35
     private SnackbarAndFabContainer snackbarAndFabContainer;
34 36
     protected LeftButtonOnClickListener leftButtonOnClickListener;
35 37
     private @Nullable SideMenu sideMenu;
36 38
 
37
-    public SingleScreenLayout(AppCompatActivity activity, @Nullable SideMenuParams sideMenuParams, ScreenParams screenParams) {
39
+    public SingleScreenLayout(AppCompatActivity activity, SideMenuParams leftSideMenuParams,
40
+                              SideMenuParams rightSideMenuParams, ScreenParams screenParams) {
38 41
         super(activity);
39 42
         this.activity = activity;
40 43
         this.screenParams = screenParams;
41
-        this.sideMenuParams = sideMenuParams;
44
+        this.leftSideMenuParams = leftSideMenuParams;
45
+        this.rightSideMenuParams = rightSideMenuParams;
42 46
         createLayout();
43 47
     }
44 48
 
45 49
     private void createLayout() {
46
-        if (sideMenuParams == null) {
50
+        if (leftSideMenuParams == null) {
47 51
             createStack(getScreenStackParent());
48 52
         } else {
49 53
             sideMenu = createSideMenu();
@@ -58,7 +62,7 @@ public class SingleScreenLayout extends RelativeLayout implements Layout {
58 62
     }
59 63
 
60 64
     private SideMenu createSideMenu() {
61
-        SideMenu sideMenu = new SideMenu(getContext(), sideMenuParams);
65
+        SideMenu sideMenu = new SideMenu(getContext(), leftSideMenuParams, rightSideMenuParams);
62 66
         RelativeLayout.LayoutParams lp = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
63 67
         addView(sideMenu, lp);
64 68
         return sideMenu;
@@ -182,16 +186,16 @@ public class SingleScreenLayout extends RelativeLayout implements Layout {
182 186
     }
183 187
 
184 188
     @Override
185
-    public void toggleSideMenuVisible(boolean animated) {
189
+    public void toggleSideMenuVisible(boolean animated, Side side) {
186 190
         if (sideMenu != null) {
187
-            sideMenu.toggleVisible(animated);
191
+            sideMenu.toggleVisible(animated, side);
188 192
         }
189 193
     }
190 194
 
191 195
     @Override
192
-    public void setSideMenuVisible(boolean animated, boolean visible) {
196
+    public void setSideMenuVisible(boolean animated, boolean visible, Side side) {
193 197
         if (sideMenu != null) {
194
-            sideMenu.setVisible(visible, animated);
198
+            sideMenu.setVisible(visible, animated, side);
195 199
         }
196 200
     }
197 201
 
@@ -233,7 +237,7 @@ public class SingleScreenLayout extends RelativeLayout implements Layout {
233 237
     @Override
234 238
     public void onSideMenuButtonClick() {
235 239
         if (sideMenu != null) {
236
-            sideMenu.openDrawer();
240
+            sideMenu.openDrawer(Side.Left);
237 241
         } else {
238 242
             final String navigatorEventId = stack.peek().getNavigatorEventId();
239 243
             NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("sideMenu", navigatorEventId);

+ 2
- 1
android/app/src/main/java/com/reactnativenavigation/params/ActivityParams.java View File

@@ -10,6 +10,7 @@ public class ActivityParams {
10 10
     public Type type;
11 11
     public ScreenParams screenParams;
12 12
     public List<ScreenParams> tabParams;
13
-    public SideMenuParams sideMenuParams;
13
+    public SideMenuParams leftSideMenuParams;
14
+    public SideMenuParams rightSideMenuParams;
14 15
     public boolean animateShow;
15 16
 }

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

@@ -3,9 +3,9 @@ package com.reactnativenavigation.params;
3 3
 import android.os.Bundle;
4 4
 
5 5
 public class NavigationParams {
6
-    public static final String SCREEN_INSTANCE_ID = "screenInstanceID";
7
-    public static final String NAVIGATOR_ID = "navigatorID";
8
-    public static final String NAVIGATOR_EVENT_ID = "navigatorEventID";
6
+    private static final String SCREEN_INSTANCE_ID = "screenInstanceID";
7
+    private static final String NAVIGATOR_ID = "navigatorID";
8
+    private static final String NAVIGATOR_EVENT_ID = "navigatorEventID";
9 9
 
10 10
     public String screenInstanceId;
11 11
     public String navigatorId;

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

@@ -1,7 +1,10 @@
1 1
 package com.reactnativenavigation.params;
2 2
 
3
+import com.reactnativenavigation.views.SideMenu;
4
+
3 5
 public class SideMenuParams {
4 6
     public String screenId;
5 7
     public NavigationParams navigationParams;
6 8
     public boolean disableOpenGesture;
9
+    public SideMenu.Side side;
7 10
 }

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

@@ -4,6 +4,8 @@ import android.os.Bundle;
4 4
 
5 5
 import com.reactnativenavigation.params.ActivityParams;
6 6
 import com.reactnativenavigation.params.AppStyle;
7
+import com.reactnativenavigation.params.SideMenuParams;
8
+import com.reactnativenavigation.views.SideMenu;
7 9
 
8 10
 public class ActivityParamsParser extends Parser {
9 11
     public static ActivityParams parse(Bundle params) {
@@ -22,7 +24,9 @@ public class ActivityParamsParser extends Parser {
22 24
         }
23 25
 
24 26
         if (hasKey(params, "sideMenu")) {
25
-            result.sideMenuParams = SideMenuParamsParser.parse(params.getBundle("sideMenu"));
27
+            SideMenuParams[] sideMenus = SideMenuParamsParser.parse(params.getBundle("sideMenu"));
28
+            result.leftSideMenuParams = sideMenus[SideMenu.Side.Left.ordinal()];
29
+            result.rightSideMenuParams = sideMenus[SideMenu.Side.Right.ordinal()];
26 30
         }
27 31
 
28 32
         result.animateShow = params.getBoolean("animateShow", true);

+ 14
- 2
android/app/src/main/java/com/reactnativenavigation/params/parsers/SideMenuParamsParser.java View File

@@ -1,17 +1,29 @@
1 1
 package com.reactnativenavigation.params.parsers;
2 2
 
3 3
 import android.os.Bundle;
4
+import android.support.annotation.Nullable;
4 5
 
5 6
 import com.reactnativenavigation.params.NavigationParams;
6 7
 import com.reactnativenavigation.params.SideMenuParams;
8
+import com.reactnativenavigation.views.SideMenu.Side;
7 9
 
8
-public class SideMenuParamsParser extends Parser {
10
+class SideMenuParamsParser extends Parser {
11
+    public static SideMenuParams[] parse(Bundle sideMenues) {
12
+        SideMenuParams[] result = new SideMenuParams[2];
13
+        result[Side.Left.ordinal()] = parseSideMenu(sideMenues.getBundle("left"), Side.Left);
14
+        result[Side.Right.ordinal()] = parseSideMenu(sideMenues.getBundle("right"), Side.Right);
15
+        return result;
16
+    }
9 17
 
10
-    public static SideMenuParams parse(Bundle sideMenu) {
18
+    private static SideMenuParams parseSideMenu(@Nullable Bundle sideMenu, Side side) {
19
+        if (sideMenu == null || sideMenu.isEmpty()) {
20
+            return null;
21
+        }
11 22
         SideMenuParams result = new SideMenuParams();
12 23
         result.screenId = sideMenu.getString("screenId");
13 24
         result.navigationParams = new NavigationParams(sideMenu.getBundle("navigationParams"));
14 25
         result.disableOpenGesture = sideMenu.getBoolean("disableOpenGesture", false);
26
+        result.side = side;
15 27
         return result;
16 28
     }
17 29
 }

+ 52
- 25
android/app/src/main/java/com/reactnativenavigation/views/SideMenu.java View File

@@ -1,7 +1,7 @@
1 1
 package com.reactnativenavigation.views;
2 2
 
3 3
 import android.content.Context;
4
-import android.support.v4.view.GravityCompat;
4
+import android.support.annotation.Nullable;
5 5
 import android.support.v4.widget.DrawerLayout;
6 6
 import android.view.Gravity;
7 7
 import android.view.ViewGroup;
@@ -12,8 +12,22 @@ import com.reactnativenavigation.screens.Screen;
12 12
 import com.reactnativenavigation.utils.ViewUtils;
13 13
 
14 14
 public class SideMenu extends DrawerLayout {
15
+    public enum Side {
16
+        Left(Gravity.LEFT), Right(Gravity.RIGHT);
15 17
 
16
-    private ContentView sideMenuView;
18
+        int gravity;
19
+
20
+        Side(int gravity) {
21
+            this.gravity = gravity;
22
+        }
23
+
24
+        public static Side fromString(String side) {
25
+            return "left".equals(side.toLowerCase()) ? Left : Right;
26
+        }
27
+    }
28
+
29
+    private ContentView leftSideMenuView;
30
+    private ContentView rightSideMenuView;
17 31
     private RelativeLayout contentContainer;
18 32
 
19 33
     public RelativeLayout getContentContainer() {
@@ -21,45 +35,54 @@ public class SideMenu extends DrawerLayout {
21 35
     }
22 36
 
23 37
     public void destroy() {
38
+        destroySideMenu(leftSideMenuView);
39
+        destroySideMenu(rightSideMenuView);
40
+    }
41
+
42
+    private void destroySideMenu(ContentView sideMenuView) {
43
+        if (sideMenuView == null) {
44
+            return;
45
+        }
24 46
         sideMenuView.unmountReactView();
25 47
         removeView(sideMenuView);
26 48
     }
27 49
 
28
-    public void setVisible(boolean visible, boolean animated) {
50
+    public void setVisible(boolean visible, boolean animated, Side side) {
29 51
         if (!isShown() && visible) {
30
-            openDrawer(animated);
52
+            openDrawer(animated, side);
31 53
         }
32 54
 
33 55
         if (isShown() && !visible) {
34
-            closeDrawer(animated);
56
+            closeDrawer(animated, side);
35 57
         }
36 58
     }
37 59
 
38
-    public void openDrawer() {
39
-        openDrawer(Gravity.LEFT);
40
-    }
41
-
42
-    public void openDrawer(boolean animated) {
43
-        openDrawer(Gravity.LEFT, animated);
60
+    public void openDrawer(Side side) {
61
+        openDrawer(side.gravity);
44 62
     }
45 63
 
46
-    public void closeDrawer(boolean animated) {
47
-        closeDrawer(Gravity.LEFT, animated);
64
+    public void openDrawer(boolean animated, Side side) {
65
+        openDrawer(side.gravity, animated);
48 66
     }
49 67
 
50
-    public void toggleVisible(boolean animated) {
51
-        if (isDrawerOpen(GravityCompat.START)) {
52
-            closeDrawer(animated);
68
+    public void toggleVisible(boolean animated, Side side) {
69
+        if (isDrawerOpen(side.gravity)) {
70
+            closeDrawer(animated, side);
53 71
         } else {
54
-            openDrawer(animated);
72
+            openDrawer(animated, side);
55 73
         }
56 74
     }
57 75
 
58
-    public SideMenu(Context context, SideMenuParams sideMenuParams) {
76
+    public void closeDrawer(boolean animated, Side side) {
77
+        closeDrawer(side.gravity, animated);
78
+    }
79
+
80
+    public SideMenu(Context context, SideMenuParams leftMenuParams, SideMenuParams rightMenuParams) {
59 81
         super(context);
60 82
         createContentContainer();
61
-        createSideMenu(sideMenuParams);
62
-        setStyle(sideMenuParams);
83
+        leftSideMenuView = createSideMenu(leftMenuParams);
84
+        rightSideMenuView = createSideMenu(rightMenuParams);
85
+        setStyle(leftMenuParams);
63 86
     }
64 87
 
65 88
     private void createContentContainer() {
@@ -69,15 +92,19 @@ public class SideMenu extends DrawerLayout {
69 92
         addView(contentContainer, lp);
70 93
     }
71 94
 
72
-    private void createSideMenu(SideMenuParams sideMenuParams) {
73
-        sideMenuView = new ContentView(getContext(), sideMenuParams.screenId, sideMenuParams.navigationParams);
95
+    private ContentView createSideMenu(@Nullable SideMenuParams params) {
96
+        if (params == null) {
97
+            return null;
98
+        }
99
+        ContentView sideMenuView = new ContentView(getContext(), params.screenId, params.navigationParams);
74 100
         LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
75
-        lp.gravity = Gravity.START;
76
-        setSideMenuWidth();
101
+        lp.gravity = params.side.gravity;
102
+        setSideMenuWidth(sideMenuView);
77 103
         addView(sideMenuView, lp);
104
+        return sideMenuView;
78 105
     }
79 106
 
80
-    private void setSideMenuWidth() {
107
+    private void setSideMenuWidth(final ContentView sideMenuView) {
81 108
         sideMenuView.setOnDisplayListener(new Screen.OnDisplayListener() {
82 109
             @Override
83 110
             public void onDisplay() {

+ 2
- 2
android/app/src/main/java/com/reactnativenavigation/views/utils/ViewMeasurer.java View File

@@ -4,8 +4,8 @@ import static android.view.View.MeasureSpec;
4 4
 
5 5
 public class ViewMeasurer {
6 6
 
7
-    public int getMeasuredHeight(int heightMeasuerSpec) {
8
-        return MeasureSpec.getSize(heightMeasuerSpec);
7
+    public int getMeasuredHeight(int heightMeasureSpec) {
8
+        return MeasureSpec.getSize(heightMeasureSpec);
9 9
     }
10 10
 
11 11
     public int getMeasuredWidth(int widthMeasureSpec) {

+ 16
- 7
src/deprecated/platformSpecificDeprecated.android.js View File

@@ -176,12 +176,21 @@ function convertDrawerParamsToSideMenuParams(drawerParams) {
176 176
     return null;
177 177
   }
178 178
 
179
-  let result = {};
179
+  let result = {
180
+    left: {},
181
+    right: {}
182
+  };
180 183
   result.disableOpenGesture = drawer.disableOpenGesture !== undefined;
181
-  result.screenId = drawer.left.screen;
182
-  addNavigatorParams(result);
183
-  result = adaptNavigationParams(result);
184
-  result.passProps = drawer.passProps;
184
+  result.left.screenId = drawer.left.screen;
185
+  addNavigatorParams(result.left);
186
+  result.left = adaptNavigationParams(result.left);
187
+  result.left.passProps = drawer.left.passProps;
188
+
189
+  result.right.screenId = drawer.right.screen;
190
+  addNavigatorParams(result.right);
191
+  result.right = adaptNavigationParams(result.right);
192
+  result.right.passProps = drawer.right.passProps;
193
+
185 194
   return result;
186 195
 }
187 196
 
@@ -301,9 +310,9 @@ function navigatorToggleDrawer(navigator, params) {
301 310
   const animated = !(params.animated === false);
302 311
   if (params.to) {
303 312
     const visible = params.to === 'open';
304
-    newPlatformSpecific.setSideMenuVisible(animated, visible);
313
+    newPlatformSpecific.setSideMenuVisible(animated, visible, params.side);
305 314
   } else {
306
-    newPlatformSpecific.toggleSideMenuVisible(animated);
315
+    newPlatformSpecific.toggleSideMenuVisible(animated, params.side);
307 316
   }
308 317
 }
309 318
 

+ 9
- 6
src/platformSpecific.android.js View File

@@ -87,17 +87,20 @@ function savePassProps(params) {
87 87
     });
88 88
   }
89 89
 
90
-  if (params.sideMenu) {
91
-    PropRegistry.save(params.sideMenu.navigationParams.screenInstanceID, params.sideMenu.passProps);
90
+  if (params.sideMenu && params.sideMenu.left) {
91
+    PropRegistry.save(params.sideMenu.left.navigationParams.screenInstanceID, params.sideMenu.left.passProps);
92
+  }
93
+  if (params.sideMenu && params.sideMenu.right) {
94
+    PropRegistry.save(params.sideMenu.right.navigationParams.screenInstanceID, params.sideMenu.right.passProps);
92 95
   }
93 96
 }
94 97
 
95
-function toggleSideMenuVisible(animated) {
96
-  NativeReactModule.toggleSideMenuVisible(animated);
98
+function toggleSideMenuVisible(animated, side) {
99
+  NativeReactModule.toggleSideMenuVisible(animated, side);
97 100
 }
98 101
 
99
-function setSideMenuVisible(animated, visible) {
100
-  NativeReactModule.setSideMenuVisible(animated, visible);
102
+function setSideMenuVisible(animated, visible, side) {
103
+  NativeReactModule.setSideMenuVisible(animated, visible, side);
101 104
 }
102 105
 
103 106
 function selectBottomTabByNavigatorId(navigatorId) {