Browse Source

left button

Guy Carmeli 8 years ago
parent
commit
5dabdc225b

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

50
     compile "com.android.support:appcompat-v7:23.0.1"
50
     compile "com.android.support:appcompat-v7:23.0.1"
51
     compile 'com.android.support:design:23.1.1'
51
     compile 'com.android.support:design:23.1.1'
52
     compile "com.facebook.react:react-native:+"  // From node_modules
52
     compile "com.facebook.react:react-native:+"  // From node_modules
53
+    compile 'com.balysv.materialmenu:material-menu-toolbar:1.5.4'
53
 
54
 
54
     testCompile "junit:junit:4.12"
55
     testCompile "junit:junit:4.12"
55
     testCompile "org.robolectric:robolectric:3.1.1"
56
     testCompile "org.robolectric:robolectric:3.1.1"

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

45
 
45
 
46
     @ReactMethod
46
     @ReactMethod
47
     public void setScreenTitleBarButtons(String screenInstanceId, String navigatorEventId, ReadableArray buttons) {
47
     public void setScreenTitleBarButtons(String screenInstanceId, String navigatorEventId, ReadableArray buttons) {
48
-        List<TitleBarButtonParams> titleBarButtons = TitleBarButtonParamsParser.parse(BundleConverter.toBundle(buttons));
48
+        List<TitleBarButtonParams> titleBarButtons = TitleBarButtonParamsParser.parseButtons(BundleConverter.toBundle(buttons));
49
         NavigationCommandsHandler.setScreenTitleBarButtons(screenInstanceId, navigatorEventId, titleBarButtons);
49
         NavigationCommandsHandler.setScreenTitleBarButtons(screenInstanceId, navigatorEventId, titleBarButtons);
50
     }
50
     }
51
 
51
 

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

7
 public class ScreenParams {
7
 public class ScreenParams {
8
     public String screenId;
8
     public String screenId;
9
     public Bundle passProps;
9
     public Bundle passProps;
10
-    public List<TitleBarButtonParams> buttons;
10
+    public List<TitleBarButtonParams> rightButtons;
11
+    public TitleBarButtonParams leftButton;
11
     public String title;
12
     public String title;
12
     public ScreenStyleParams styleParams;
13
     public ScreenStyleParams styleParams;
13
     public List<TopTabParams> topTabParams;
14
     public List<TopTabParams> topTabParams;

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

11
     private static final String KEY_NAVIGATOR_EVENT_ID = "navigatorEventID";
11
     private static final String KEY_NAVIGATOR_EVENT_ID = "navigatorEventID";
12
     private static final String KEY_PROPS = "passProps";
12
     private static final String KEY_PROPS = "passProps";
13
     private static final String KEY_NAVIGATION_PARAMS = "navigationParams";
13
     private static final String KEY_NAVIGATION_PARAMS = "navigationParams";
14
-    private static final String KEY_BUTTONS = "titleBarButtons";
14
+    private static final String KEY_RIGHT_BUTTONS = "rightButtons";
15
+    private static final String KEY_LEFT_BUTTON = "leftButton";
15
     private static final String STYLE_PARAMS = "styleParams";
16
     private static final String STYLE_PARAMS = "styleParams";
16
     public static final String TOP_TABS = "topTabs";
17
     public static final String TOP_TABS = "topTabs";
17
 
18
 
25
         result.navigationParams = params.getBundle(KEY_NAVIGATION_PARAMS);
26
         result.navigationParams = params.getBundle(KEY_NAVIGATION_PARAMS);
26
         result.navigatorEventId = result.navigationParams.getString(KEY_NAVIGATOR_EVENT_ID);
27
         result.navigatorEventId = result.navigationParams.getString(KEY_NAVIGATOR_EVENT_ID);
27
         result.screenInstanceId = result.navigationParams.getString(KEY_SCREEN_INSTANCE_ID);
28
         result.screenInstanceId = result.navigationParams.getString(KEY_SCREEN_INSTANCE_ID);
28
-        result.buttons = TitleBarButtonParamsParser.parse(params.getBundle(KEY_BUTTONS));
29
+        if (hasKey(params, KEY_RIGHT_BUTTONS)) {
30
+            result.rightButtons = TitleBarButtonParamsParser.parseButtons(params.getBundle(KEY_RIGHT_BUTTONS));
31
+        }
32
+        if (hasKey(params, KEY_LEFT_BUTTON)) {
33
+            result.leftButton = TitleBarButtonParamsParser.parseSingleButton(params.getBundle(KEY_LEFT_BUTTON));
34
+        }
29
         result.title = params.getString(KEY_TITLE);
35
         result.title = params.getString(KEY_TITLE);
30
         result.styleParams = ScreenStyleParamsParser.parse(params.getBundle(STYLE_PARAMS));
36
         result.styleParams = ScreenStyleParamsParser.parse(params.getBundle(STYLE_PARAMS));
31
         if (hasKey(params, TOP_TABS)) {
37
         if (hasKey(params, TOP_TABS)) {

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

10
 import java.util.List;
10
 import java.util.List;
11
 
11
 
12
 public class TitleBarButtonParamsParser extends Parser {
12
 public class TitleBarButtonParamsParser extends Parser {
13
-    public static List<TitleBarButtonParams> parse(Bundle params) {
13
+    public static List<TitleBarButtonParams> parseButtons(Bundle params) {
14
         List<TitleBarButtonParams> result = new ArrayList<>();
14
         List<TitleBarButtonParams> result = new ArrayList<>();
15
-        if (params == null) {
16
-            return result;
17
-        }
18
 
15
 
19
         for (String key : params.keySet()) {
16
         for (String key : params.keySet()) {
20
-            result.add(parseItem(params.getBundle(key)));
17
+            result.add(parseSingleButton(params.getBundle(key)));
21
         }
18
         }
22
         return result;
19
         return result;
23
     }
20
     }
24
 
21
 
25
-    private static TitleBarButtonParams parseItem(Bundle bundle) {
22
+    public static TitleBarButtonParams parseSingleButton(Bundle bundle) {
26
         TitleBarButtonParams result = new TitleBarButtonParams();
23
         TitleBarButtonParams result = new TitleBarButtonParams();
27
         result.label = bundle.getString("title");
24
         result.label = bundle.getString("title");
28
         if (hasKey(bundle,"icon")) {
25
         if (hasKey(bundle,"icon")) {

+ 6
- 2
android/app/src/main/java/com/reactnativenavigation/screens/Screen.java View File

15
 import com.reactnativenavigation.utils.SdkSupports;
15
 import com.reactnativenavigation.utils.SdkSupports;
16
 import com.reactnativenavigation.utils.ViewUtils;
16
 import com.reactnativenavigation.utils.ViewUtils;
17
 import com.reactnativenavigation.views.ScrollDirectionListener;
17
 import com.reactnativenavigation.views.ScrollDirectionListener;
18
+import com.reactnativenavigation.views.TitleBarBackButtonListener;
18
 import com.reactnativenavigation.views.TopBar;
19
 import com.reactnativenavigation.views.TopBar;
19
 
20
 
20
 import java.util.List;
21
 import java.util.List;
25
 public abstract class Screen extends RelativeLayout implements ScrollDirectionListener.OnScrollChanged {
26
 public abstract class Screen extends RelativeLayout implements ScrollDirectionListener.OnScrollChanged {
26
 
27
 
27
     protected final ScreenParams screenParams;
28
     protected final ScreenParams screenParams;
29
+    private final TitleBarBackButtonListener titleBarBackButtonListener;
28
     protected TopBar topBar;
30
     protected TopBar topBar;
29
     private VisibilityAnimator topBarVisibilityAnimator;
31
     private VisibilityAnimator topBarVisibilityAnimator;
30
 
32
 
31
-    public Screen(Context context, ScreenParams screenParams) {
33
+    public Screen(Context context, ScreenParams screenParams, TitleBarBackButtonListener titleBarBackButtonListener) {
32
         super(context);
34
         super(context);
33
         this.screenParams = screenParams;
35
         this.screenParams = screenParams;
36
+        this.titleBarBackButtonListener = titleBarBackButtonListener;
34
 
37
 
35
         createViews();
38
         createViews();
36
         setStyle(screenParams.styleParams);
39
         setStyle(screenParams.styleParams);
45
     protected abstract void createContent();
48
     protected abstract void createContent();
46
 
49
 
47
     private void createTitleBar() {
50
     private void createTitleBar() {
48
-        topBar.addTitleBarAndSetButtons(screenParams.buttons, screenParams.navigatorEventId);
51
+        topBar.addTitleBarAndSetButtons(screenParams.rightButtons, screenParams.leftButton,
52
+                titleBarBackButtonListener, screenParams.navigatorEventId);
49
         topBar.setTitle(screenParams.title);
53
         topBar.setTitle(screenParams.title);
50
     }
54
     }
51
 
55
 

+ 5
- 2
android/app/src/main/java/com/reactnativenavigation/screens/ScreenFactory.java View File

3
 import android.content.Context;
3
 import android.content.Context;
4
 
4
 
5
 import com.reactnativenavigation.params.ScreenParams;
5
 import com.reactnativenavigation.params.ScreenParams;
6
+import com.reactnativenavigation.views.TitleBarBackButtonListener;
6
 
7
 
7
 public class ScreenFactory {
8
 public class ScreenFactory {
8
-    public static Screen create(Context context, ScreenParams screenParams) {
9
+    public static Screen create(Context context,
10
+                                ScreenParams screenParams,
11
+                                TitleBarBackButtonListener titleBarBackButtonListener) {
9
         if (screenParams.hasTopTabs()) {
12
         if (screenParams.hasTopTabs()) {
10
             return new TabbedScreen(context, screenParams);
13
             return new TabbedScreen(context, screenParams);
11
         } else {
14
         } else {
12
-            return new SingleScreen(context, screenParams);
15
+            return new SingleScreen(context, screenParams, titleBarBackButtonListener);
13
         }
16
         }
14
     }
17
     }
15
 }
18
 }

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

6
 
6
 
7
 import com.reactnativenavigation.params.ScreenParams;
7
 import com.reactnativenavigation.params.ScreenParams;
8
 import com.reactnativenavigation.params.TitleBarButtonParams;
8
 import com.reactnativenavigation.params.TitleBarButtonParams;
9
+import com.reactnativenavigation.views.TitleBarBackButtonListener;
9
 
10
 
10
 import java.util.List;
11
 import java.util.List;
11
 import java.util.Stack;
12
 import java.util.Stack;
13
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
14
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
14
 
15
 
15
 // TODO there's really no reason for ScreenStack to extend FrameLayout. All screens can be added to parent.
16
 // TODO there's really no reason for ScreenStack to extend FrameLayout. All screens can be added to parent.
16
-public class ScreenStack extends FrameLayout {
17
+public class ScreenStack extends FrameLayout implements TitleBarBackButtonListener {
17
     private Stack<Screen> stack = new Stack<>();
18
     private Stack<Screen> stack = new Stack<>();
18
 
19
 
19
     public ScreenStack(Context context, ScreenParams initialScreenParams) {
20
     public ScreenStack(Context context, ScreenParams initialScreenParams) {
20
         super(context);
21
         super(context);
21
         setLayoutTransition(new LayoutTransition());
22
         setLayoutTransition(new LayoutTransition());
22
-        push(initialScreenParams);
23
+        pushInitialScreen(initialScreenParams);
24
+    }
25
+
26
+    private void pushInitialScreen(ScreenParams initialScreenParams) {
27
+        addScreen(initialScreenParams);
23
     }
28
     }
24
 
29
 
25
     public void push(ScreenParams screenParams) {
30
     public void push(ScreenParams screenParams) {
26
-        if (isEmpty()) {
27
-            addScreen(screenParams);
28
-        } else {
29
-            Screen previous = stack.peek();
30
-            addScreen(screenParams);
31
-            removePreviousWithoutUnmount(previous);
32
-        }
31
+        Screen previous = stack.peek();
32
+        addScreen(screenParams);
33
+        removePreviousWithoutUnmount(previous);
33
     }
34
     }
34
 
35
 
35
     private void addScreen(ScreenParams screenParams) {
36
     private void addScreen(ScreenParams screenParams) {
36
-        Screen screen = ScreenFactory.create(getContext(), screenParams);
37
+        Screen screen = ScreenFactory.create(getContext(), screenParams, this);
37
         addView(screen, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
38
         addView(screen, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
38
         stack.push(screen);
39
         stack.push(screen);
39
     }
40
     }
75
         stack.clear();
76
         stack.clear();
76
     }
77
     }
77
 
78
 
78
-    public boolean isEmpty() {
79
-        return stack.isEmpty();
80
-    }
81
-
82
     public int getStackSize() {
79
     public int getStackSize() {
83
         return stack.size();
80
         return stack.size();
84
     }
81
     }
122
         }
119
         }
123
     }
120
     }
124
 
121
 
122
+    @Override
123
+    public void onTitleBarBackPress() {
124
+        if (canPop()) {
125
+            pop();
126
+        }
127
+    }
125
 
128
 
126
     //    /**
129
     //    /**
127
 //     * Remove the ScreenStack from {@code parent} while preventing all child react views from getting unmounted
130
 //     * Remove the ScreenStack from {@code parent} while preventing all child react views from getting unmounted

+ 4
- 2
android/app/src/main/java/com/reactnativenavigation/screens/SingleScreen.java View File

5
 
5
 
6
 import com.reactnativenavigation.params.ScreenParams;
6
 import com.reactnativenavigation.params.ScreenParams;
7
 import com.reactnativenavigation.views.ContentView;
7
 import com.reactnativenavigation.views.ContentView;
8
+import com.reactnativenavigation.views.TitleBarBackButtonListener;
8
 
9
 
9
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
10
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
10
 
11
 
12
 
13
 
13
     private ContentView contentView;
14
     private ContentView contentView;
14
 
15
 
15
-    public SingleScreen(Context context, ScreenParams screenParams) {
16
-        super(context, screenParams);
16
+    public SingleScreen(Context context, ScreenParams screenParams,
17
+                        TitleBarBackButtonListener titleBarBarBackButtonListener) {
18
+        super(context, screenParams, titleBarBarBackButtonListener);
17
     }
19
     }
18
 
20
 
19
     @Override
21
     @Override

+ 68
- 0
android/app/src/main/java/com/reactnativenavigation/views/LeftButton.java View File

1
+package com.reactnativenavigation.views;
2
+
3
+import android.content.Context;
4
+import android.graphics.Color;
5
+import android.view.View;
6
+
7
+import com.balysv.materialmenu.MaterialMenuDrawable;
8
+import com.reactnativenavigation.params.TitleBarButtonParams;
9
+
10
+// TODO: replace with vector menu drawable
11
+public class LeftButton extends MaterialMenuDrawable implements View.OnClickListener {
12
+
13
+    private static int getColor(TitleBarButtonParams params) {
14
+        return params != null && params.color.hasColor() ?
15
+                params.color.getColor() :
16
+                Color.BLACK;
17
+    }
18
+
19
+    private TitleBarButtonParams params;
20
+    private final TitleBarBackButtonListener titleBarBackButtonListener;
21
+    private final String navigatorEventId;
22
+
23
+    public LeftButton(Context context,
24
+                      TitleBarButtonParams params,
25
+                      TitleBarBackButtonListener titleBarBackButtonListener,
26
+                      String navigatorEventId) {
27
+        super(context, getColor(params), Stroke.THIN);
28
+        this.params = params;
29
+        this.titleBarBackButtonListener = titleBarBackButtonListener;
30
+        this.navigatorEventId = navigatorEventId;
31
+        setInitialState();
32
+    }
33
+
34
+    private void setInitialState() {
35
+        if (params != null) {
36
+            setIconState(getIconStateFromId(params.eventId));
37
+        } else {
38
+            setVisible(false);
39
+        }
40
+    }
41
+
42
+    @Override
43
+    public void onClick(View v) {
44
+        if (isBackButton()) {
45
+            titleBarBackButtonListener.onTitleBarBackPress();
46
+        }
47
+    }
48
+
49
+    // TODO: move to parser
50
+    public IconState getIconStateFromId(String id) {
51
+        switch (id) {
52
+            case "back":
53
+                return IconState.ARROW;
54
+            case "cancel":
55
+                return IconState.X;
56
+            case "accept":
57
+                return IconState.CHECK;
58
+            case "sideMenu":
59
+                return IconState.BURGER;
60
+            default:
61
+                throw new RuntimeException("Unsupported button type " + id);
62
+        }
63
+    }
64
+
65
+    private boolean isBackButton() {
66
+        return getIconState() == IconState.ARROW;
67
+    }
68
+}

+ 24
- 6
android/app/src/main/java/com/reactnativenavigation/views/TitleBar.java View File

18
         super(context);
18
         super(context);
19
     }
19
     }
20
 
20
 
21
-    public void setButtons(List<TitleBarButtonParams> buttons, String navigatorEventId) {
21
+    public void setRightButtons(List<TitleBarButtonParams> rightButtons, String navigatorEventId) {
22
         Menu menu = getMenu();
22
         Menu menu = getMenu();
23
         menu.clear();
23
         menu.clear();
24
 
24
 
25
-        for (int i = 0; i < buttons.size(); i++) {
26
-            final TitleBarButton button = new TitleBarButton(menu, this, buttons.get(i), navigatorEventId);
27
-            // Add button in reverse order because in iOS index 0 starts at right
28
-            final int index = buttons.size() - i - 1;
29
-            button.addToMenu(index);
25
+        if (rightButtons == null) {
26
+            return;
30
         }
27
         }
28
+
29
+        addButtonsToTitleBar(rightButtons, navigatorEventId, menu);
30
+    }
31
+
32
+    private void addButtonsToTitleBar(List<TitleBarButtonParams> rightButtons, String navigatorEventId, Menu menu) {
33
+        for (int i = 0; i < rightButtons.size(); i++) {
34
+            final TitleBarButton button = new TitleBarButton(menu, this, rightButtons.get(i), navigatorEventId);
35
+            addButtonInReverseOrder(rightButtons, i, button);
36
+        }
37
+    }
38
+
39
+    private void addButtonInReverseOrder(List<TitleBarButtonParams> rightButtons, int i, TitleBarButton button) {
40
+        final int index = rightButtons.size() - i - 1;
41
+        button.addToMenu(index);
42
+    }
43
+
44
+    public void setLeftButton(TitleBarButtonParams leftButtonParams,
45
+                               TitleBarBackButtonListener titleBarBackButtonListener, String navigatorEventId) {
46
+        LeftButton leftButton = new LeftButton(getContext(), leftButtonParams, titleBarBackButtonListener, navigatorEventId);
47
+        setNavigationOnClickListener(leftButton);
48
+        setNavigationIcon(leftButton);
31
     }
49
     }
32
 
50
 
33
     public void setHideOnScroll(boolean hideOnScroll) {
51
     public void setHideOnScroll(boolean hideOnScroll) {

+ 5
- 0
android/app/src/main/java/com/reactnativenavigation/views/TitleBarBackButtonListener.java View File

1
+package com.reactnativenavigation.views;
2
+
3
+public interface TitleBarBackButtonListener {
4
+    void onTitleBarBackPress();
5
+}

+ 6
- 3
android/app/src/main/java/com/reactnativenavigation/views/TopBar.java View File

21
         setId(ViewUtils.generateViewId());
21
         setId(ViewUtils.generateViewId());
22
     }
22
     }
23
 
23
 
24
-    public void addTitleBarAndSetButtons(List<TitleBarButtonParams> buttons, String navigatorEventId) {
24
+    public void addTitleBarAndSetButtons(List<TitleBarButtonParams> rightButtons, TitleBarButtonParams leftButton,
25
+                                         TitleBarBackButtonListener titleBarBackButtonListener,
26
+                                         String navigatorEventId) {
25
         titleBar = new TitleBar(getContext());
27
         titleBar = new TitleBar(getContext());
26
         addView(titleBar);
28
         addView(titleBar);
27
-        titleBar.setButtons(buttons, navigatorEventId);
29
+        titleBar.setRightButtons(rightButtons, navigatorEventId);
30
+        titleBar.setLeftButton(leftButton, titleBarBackButtonListener, navigatorEventId);
28
     }
31
     }
29
 
32
 
30
     public void setTitle(String title) {
33
     public void setTitle(String title) {
40
     }
43
     }
41
 
44
 
42
     public void setTitleBarButtons(String navigatorEventId, List<TitleBarButtonParams> titleBarButtons) {
45
     public void setTitleBarButtons(String navigatorEventId, List<TitleBarButtonParams> titleBarButtons) {
43
-        titleBar.setButtons(titleBarButtons, navigatorEventId);
46
+        titleBar.setRightButtons(titleBarButtons, navigatorEventId);
44
     }
47
     }
45
 
48
 
46
     public TabLayout initTabs() {
49
     public TabLayout initTabs() {

+ 34
- 3
src/deprecated/platformSpecificDeprecated.android.js View File

136
   }
136
   }
137
 }
137
 }
138
 
138
 
139
+// TODO: add left buttons here
139
 function navigatorSetButtons(navigator, navigatorEventID, params) {
140
 function navigatorSetButtons(navigator, navigatorEventID, params) {
140
   if (params.rightButtons) {
141
   if (params.rightButtons) {
141
     params.rightButtons.forEach(function(button) {
142
     params.rightButtons.forEach(function(button) {
229
   Object.assign(screen, Screen.navigatorButtons);
230
   Object.assign(screen, Screen.navigatorButtons);
230
 
231
 
231
   // Get image uri from image id
232
   // Get image uri from image id
232
-  const rightButtons = screen.navigatorButtons ? screen.navigatorButtons.rightButtons : null;
233
-
233
+  const rightButtons = getRightButtons(screen);
234
   if (rightButtons) {
234
   if (rightButtons) {
235
     rightButtons.forEach(function(button) {
235
     rightButtons.forEach(function(button) {
236
       if (button.icon) {
236
       if (button.icon) {
242
     });
242
     });
243
   }
243
   }
244
 
244
 
245
-  screen.titleBarButtons = rightButtons;
245
+  const leftButton = getLeftButton(screen);
246
+  if (leftButton) {
247
+    if (leftButton.icon) {
248
+      const icon = resolveAssetSource(leftButton.icon);
249
+      if (icon) {
250
+        leftButton.icon = icon.uri;
251
+      }
252
+    }
253
+  }
254
+
255
+  if (rightButtons) {
256
+    screen.rightButtons = rightButtons;
257
+  }
258
+  if (leftButton) {
259
+    screen.leftButton = leftButton;
260
+  }
261
+}
262
+
263
+function getLeftButton(screen) {
264
+  if (screen.navigatorButtons) {
265
+    return screen.navigatorButtons.leftButton;
266
+  }
267
+
268
+  return screen.leftButton
269
+}
270
+
271
+function getRightButtons(screen) {
272
+  if (screen.navigatorButtons) {
273
+    return screen.navigatorButtons.rightButtons;
274
+  }
275
+
276
+  return screen.rightButtons
246
 }
277
 }
247
 
278
 
248
 function addNavigationStyleParams(screen) {
279
 function addNavigationStyleParams(screen) {