Browse Source

Invoke onNavigationButtonPressed on button press (#2755)

Guy Carmeli 6 years ago
parent
commit
7ae89a8f75
No account linked to committer's email address
19 changed files with 186 additions and 26 deletions
  1. 6
    5
      lib/android/app/src/main/java/com/reactnativenavigation/parse/Button.java
  2. 14
    0
      lib/android/app/src/main/java/com/reactnativenavigation/utils/ViewUtils.java
  3. 9
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/BottomTabsController.java
  4. 5
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ComponentViewController.java
  5. 5
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/Navigator.java
  6. 6
    1
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/SideMenuController.java
  7. 6
    1
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/StackController.java
  8. 2
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ViewController.java
  9. 5
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsController.java
  10. 5
    8
      lib/android/app/src/main/java/com/reactnativenavigation/views/StackLayout.java
  11. 9
    1
      lib/android/app/src/test/java/com/reactnativenavigation/mocks/SimpleViewController.java
  12. 11
    0
      lib/android/app/src/test/java/com/reactnativenavigation/utils/TitleBarHelper.java
  13. 15
    5
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/BottomTabsControllerTest.java
  14. 7
    0
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/ComponentViewControllerTest.java
  15. 5
    0
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/ParentControllerTest.java
  16. 11
    3
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/StackControllerTest.java
  17. 8
    0
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TopTabsViewControllerTest.java
  18. 5
    0
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/ViewControllerTest.java
  19. 52
    2
      lib/android/app/src/test/java/com/reactnativenavigation/views/TopBarTest.java

+ 6
- 5
lib/android/app/src/main/java/com/reactnativenavigation/parse/Button.java View File

@@ -4,6 +4,7 @@ import android.support.annotation.ColorInt;
4 4
 import android.view.MenuItem;
5 5
 
6 6
 import com.reactnativenavigation.parse.params.Bool;
7
+import com.reactnativenavigation.parse.params.NullBool;
7 8
 import com.reactnativenavigation.parse.parsers.BoolParser;
8 9
 
9 10
 import org.json.JSONArray;
@@ -15,15 +16,15 @@ import static com.reactnativenavigation.parse.Options.NO_INT_VALUE;
15 16
 
16 17
 public class Button {
17 18
 	public String id;
18
-	public Text title;
19
-	public Bool enabled;
20
-	public Bool disableIconTint;
19
+	public Text title = new NullText();
20
+	public Bool enabled = new NullBool();
21
+	public Bool disableIconTint = new NullBool();
21 22
 	public int showAsAction;
22 23
 	@ColorInt public int buttonColor;
23 24
 	public int buttonFontSize;
24
-	private Text buttonFontWeight;
25
+	private Text buttonFontWeight = new NullText();
25 26
 	public Text icon = new NullText();
26
-	public Text testId;
27
+	public Text testId = new NullText();
27 28
 
28 29
 	private static Button parseJson(JSONObject json)  {
29 30
 		Button button = new Button();

+ 14
- 0
lib/android/app/src/main/java/com/reactnativenavigation/utils/ViewUtils.java View File

@@ -26,6 +26,20 @@ public class ViewUtils {
26 26
         return null;
27 27
     }
28 28
 
29
+    public static <T> List<T> findChildrenByClassRecursive(ViewGroup root, Class clazz) {
30
+        ArrayList<T> ret = new ArrayList<>();
31
+        for (int i = 0; i < root.getChildCount(); i++) {
32
+            View view = root.getChildAt(i);
33
+            if (view instanceof ViewGroup) {
34
+                ret.addAll(findChildrenByClassRecursive((ViewGroup) view, clazz));
35
+            }
36
+            if (clazz.isAssignableFrom(view.getClass())) {
37
+                ret.add((T) view);
38
+            }
39
+        }
40
+        return ret;
41
+    }
42
+
29 43
     public static <T> List<T> findChildrenByClass(ViewGroup root, Class clazz) {
30 44
         List<T> ret = new ArrayList<>();
31 45
         for (int i = 0; i < root.getChildCount(); i++) {

+ 9
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/BottomTabsController.java View File

@@ -68,6 +68,15 @@ public class BottomTabsController extends ParentController implements AHBottomNa
68 68
 		return !tabs.isEmpty() && tabs.get(bottomTabs.getCurrentItem()).handleBack();
69 69
 	}
70 70
 
71
+    @Override
72
+    public void sendOnNavigationButtonPressed(String buttonId) {
73
+        getCurrentTab().sendOnNavigationButtonPressed(buttonId);
74
+    }
75
+
76
+    private ViewController getCurrentTab() {
77
+        return tabs.get(bottomTabs.getCurrentItem());
78
+    }
79
+
71 80
     @Override
72 81
     public boolean onTabSelected(int index, boolean wasSelected) {
73 82
         if (wasSelected) return false;

+ 5
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ComponentViewController.java View File

@@ -36,6 +36,11 @@ public class ComponentViewController extends ViewController<ComponentLayout> imp
36 36
         super.onViewDisappear();
37 37
     }
38 38
 
39
+    @Override
40
+    public void sendOnNavigationButtonPressed(String buttonId) {
41
+        getView().sendOnNavigationButtonPressed(buttonId);
42
+    }
43
+
39 44
     @Override
40 45
     public void applyOptions(Options options) {
41 46
         view.applyOptions(options);

+ 5
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/Navigator.java View File

@@ -52,6 +52,11 @@ public class Navigator extends ParentController {
52 52
         super.destroy();
53 53
     }
54 54
 
55
+    @Override
56
+    public void sendOnNavigationButtonPressed(String buttonId) {
57
+
58
+    }
59
+
55 60
     public void setRoot(final ViewController viewController, Promise promise) {
56 61
         if (root != null) {
57 62
             root.destroy();

+ 6
- 1
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/SideMenuController.java View File

@@ -32,7 +32,12 @@ public class SideMenuController extends ParentController {
32 32
         return new DrawerLayout(getActivity());
33 33
 	}
34 34
 
35
-	@NonNull
35
+    @Override
36
+    public void sendOnNavigationButtonPressed(String buttonId) {
37
+        centerController.sendOnNavigationButtonPressed(buttonId);
38
+    }
39
+
40
+    @NonNull
36 41
 	@Override
37 42
 	public Collection<ViewController> getChildControllers() {
38 43
 		ArrayList<ViewController> children = new ArrayList<>();

+ 6
- 1
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/StackController.java View File

@@ -192,10 +192,15 @@ public class StackController extends ParentController <StackLayout> {
192 192
         return false;
193 193
 	}
194 194
 
195
+    @Override
196
+    public void sendOnNavigationButtonPressed(String buttonId) {
197
+        peek().sendOnNavigationButtonPressed(buttonId);
198
+    }
199
+
195 200
     @NonNull
196 201
     @Override
197 202
     protected StackLayout createView() {
198
-        stackLayout = new StackLayout(getActivity());
203
+        stackLayout = new StackLayout(getActivity(), this::sendOnNavigationButtonPressed);
199 204
         return stackLayout;
200 205
     }
201 206
 

+ 2
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ViewController.java View File

@@ -191,6 +191,8 @@ public abstract class ViewController<T extends ViewGroup> implements ViewTreeObs
191 191
         }
192 192
     }
193 193
 
194
+    public abstract void sendOnNavigationButtonPressed(String buttonId);
195
+
194 196
     protected boolean isViewShown() {
195 197
         return !isDestroyed && getView().isShown();
196 198
     }

+ 5
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsController.java View File

@@ -68,6 +68,11 @@ public class TopTabsController extends ParentController<TopTabsViewPager> implem
68 68
         performOnCurrentTab(ViewController::onViewDisappear);
69 69
     }
70 70
 
71
+    @Override
72
+    public void sendOnNavigationButtonPressed(String buttonId) {
73
+        performOnCurrentTab(tab -> tab.sendOnNavigationButtonPressed(buttonId));
74
+    }
75
+
71 76
     @Override
72 77
     public void applyOptions(Options options) {
73 78
         getView().applyOptions(options);

+ 5
- 8
lib/android/app/src/main/java/com/reactnativenavigation/views/StackLayout.java View File

@@ -1,5 +1,6 @@
1 1
 package com.reactnativenavigation.views;
2 2
 
3
+import android.annotation.SuppressLint;
3 4
 import android.content.Context;
4 5
 import android.support.annotation.RestrictTo;
5 6
 import android.support.v4.view.ViewPager;
@@ -17,13 +18,14 @@ import com.reactnativenavigation.utils.CompatUtils;
17 18
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
18 19
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
19 20
 
20
-public class StackLayout extends RelativeLayout implements TitleBarButton.OnClickListener {
21
+@SuppressLint("ViewConstructor")
22
+public class StackLayout extends RelativeLayout {
21 23
 
22 24
     private final TopBar topBar;
23 25
 
24
-    public StackLayout(Context context) {
26
+    public StackLayout(Context context, TitleBarButton.OnClickListener topBarButtonClickListener) {
25 27
         super(context);
26
-        topBar = new TopBar(context, this, this);
28
+        topBar = new TopBar(context, topBarButtonClickListener, this);
27 29
         topBar.setId(CompatUtils.generateViewId());
28 30
         createLayout();
29 31
         setContentDescription("StackLayout");
@@ -33,11 +35,6 @@ public class StackLayout extends RelativeLayout implements TitleBarButton.OnClic
33 35
         addView(topBar, MATCH_PARENT, WRAP_CONTENT);
34 36
     }
35 37
 
36
-    @Override
37
-    public void onPress(String buttonId) {
38
-
39
-    }
40
-
41 38
     public void applyOptions(Options options, ReactComponent component) {
42 39
         new OptionsPresenter(topBar, component).applyOptions(options);
43 40
     }

+ 9
- 1
lib/android/app/src/test/java/com/reactnativenavigation/mocks/SimpleViewController.java View File

@@ -15,13 +15,21 @@ import com.reactnativenavigation.views.TopBar;
15 15
 
16 16
 public class SimpleViewController extends ViewController<FrameLayout> {
17 17
 
18
+    private SimpleView simpleView;
19
+
18 20
     public SimpleViewController(final Activity activity, String id, Options options) {
19 21
         super(activity, id, options);
20 22
     }
21 23
 
22 24
     @Override
23 25
     protected FrameLayout createView() {
24
-        return new SimpleView(getActivity());
26
+        simpleView = new SimpleView(getActivity());
27
+        return simpleView;
28
+    }
29
+
30
+    @Override
31
+    public void sendOnNavigationButtonPressed(String buttonId) {
32
+        simpleView.sendOnNavigationButtonPressed(buttonId);
25 33
     }
26 34
 
27 35
     @Override

+ 11
- 0
lib/android/app/src/test/java/com/reactnativenavigation/utils/TitleBarHelper.java View File

@@ -0,0 +1,11 @@
1
+package com.reactnativenavigation.utils;
2
+
3
+import android.support.v7.widget.Toolbar;
4
+import android.view.View;
5
+import android.widget.TextView;
6
+
7
+public class TitleBarHelper {
8
+    public static View getRightButton(Toolbar toolbar, int index) {
9
+        return (View) ViewUtils.findChildrenByClassRecursive(toolbar, TextView.class).get(index);
10
+    }
11
+}

+ 15
- 5
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/BottomTabsControllerTest.java View File

@@ -45,11 +45,11 @@ public class BottomTabsControllerTest extends BaseTest {
45 45
         super.beforeEach();
46 46
         activity = newActivity();
47 47
         uut = new BottomTabsController(activity, imageLoaderMock, "uut", new Options());
48
-        child1 = new SimpleViewController(activity, "child1", tabOptions);
49
-        child2 = new SimpleViewController(activity, "child2", tabOptions);
50
-        child3 = new SimpleViewController(activity, "child3", tabOptions);
51
-        child4 = new SimpleViewController(activity, "child4", tabOptions);
52
-        child5 = new SimpleViewController(activity, "child5", tabOptions);
48
+        child1 = spy(new SimpleViewController(activity, "child1", tabOptions));
49
+        child2 = spy(new SimpleViewController(activity, "child2", tabOptions));
50
+        child3 = spy(new SimpleViewController(activity, "child3", tabOptions));
51
+        child4 = spy(new SimpleViewController(activity, "child4", tabOptions));
52
+        child5 = spy(new SimpleViewController(activity, "child5", tabOptions));
53 53
     }
54 54
 
55 55
     @Test
@@ -140,6 +140,16 @@ public class BottomTabsControllerTest extends BaseTest {
140 140
         assertThat(optionsCaptor.getValue().bottomTabsOptions.color.hasValue()).isFalse();
141 141
     }
142 142
 
143
+    @Test
144
+    public void buttonPressInvokedOnCurrentTab() throws Exception {
145
+        uut.setTabs(createTabs());
146
+        uut.ensureViewIsCreated();
147
+        uut.selectTabAtIndex(1);
148
+
149
+        uut.sendOnNavigationButtonPressed("btn1");
150
+        verify(child2, times(1)).sendOnNavigationButtonPressed("btn1");
151
+    }
152
+
143 153
     @NonNull
144 154
     private List<ViewController> createTabs() {
145 155
         return Arrays.asList(child1, child2, child3, child4, child5);

+ 7
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/ComponentViewControllerTest.java View File

@@ -67,4 +67,11 @@ public class ComponentViewControllerTest extends BaseTest {
67 67
         when(view.isReady()).thenReturn(true);
68 68
         assertThat(uut.isViewShown()).isTrue();
69 69
     }
70
+
71
+    @Test
72
+    public void onNavigationButtonPressInvokedOnReactComponent() throws Exception {
73
+        uut.ensureViewIsCreated();
74
+        uut.sendOnNavigationButtonPressed("btn1");
75
+        verify(view, times(1)).sendOnNavigationButtonPressed("btn1");
76
+    }
70 77
 }

+ 5
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/ParentControllerTest.java View File

@@ -51,6 +51,11 @@ public class ParentControllerTest extends BaseTest {
51 51
                 return layout;
52 52
             }
53 53
 
54
+            @Override
55
+            public void sendOnNavigationButtonPressed(String buttonId) {
56
+
57
+            }
58
+
54 59
             @NonNull
55 60
             @Override
56 61
             public Collection<ViewController> getChildControllers() {

+ 11
- 3
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/StackControllerTest.java View File

@@ -35,9 +35,9 @@ public class StackControllerTest extends BaseTest {
35 35
         super.beforeEach();
36 36
         activity = newActivity();
37 37
         uut = new StackController(activity, "uut", new Options());
38
-        child1 = new SimpleViewController(activity, "child1", new Options());
39
-        child2 = new SimpleViewController(activity, "child2", new Options());
40
-        child3 = new SimpleViewController(activity, "child3", new Options());
38
+        child1 = spy(new SimpleViewController(activity, "child1", new Options()));
39
+        child2 = spy(new SimpleViewController(activity, "child2", new Options()));
40
+        child3 = spy(new SimpleViewController(activity, "child3", new Options()));
41 41
     }
42 42
 
43 43
     @Test
@@ -381,6 +381,14 @@ public class StackControllerTest extends BaseTest {
381 381
         assertThat(ViewHelper.isVisible(uut.getTopBar().getTopTabs())).isFalse();
382 382
     }
383 383
 
384
+    @Test
385
+    public void buttonPressInvokedOnCurrentStack() throws Exception {
386
+        uut.ensureViewIsCreated();
387
+        uut.push(child1, new MockPromise());
388
+        uut.sendOnNavigationButtonPressed("btn1");
389
+        verify(child1, times(1)).sendOnNavigationButtonPressed("btn1");
390
+    }
391
+
384 392
     private void assertContainsOnlyId(String... ids) {
385 393
         assertThat(uut.size()).isEqualTo(ids.length);
386 394
         assertThat(uut.getChildControllers()).extracting((Extractor<ViewController, String>) ViewController::getId).containsOnly(ids);

+ 8
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TopTabsViewControllerTest.java View File

@@ -232,6 +232,14 @@ public class TopTabsViewControllerTest extends BaseTest {
232 232
         assertThat(ViewHelper.isVisible(stackController.getTopBar().getTopTabs())).isFalse();
233 233
     }
234 234
 
235
+    @Test
236
+    public void onNavigationButtonPressInvokedOnCurrentTab() throws Exception {
237
+        uut.ensureViewIsCreated();
238
+        uut.switchToTab(1);
239
+        uut.sendOnNavigationButtonPressed("btn1");
240
+        verify(tabControllers.get(1), times(1)).sendOnNavigationButtonPressed("btn1");
241
+    }
242
+
235 243
     private IReactView tab(TopTabsViewPager topTabs, final int index) {
236 244
         return (IReactView) ((ViewGroup) topTabs.getChildAt(index)).getChildAt(0);
237 245
     }

+ 5
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/ViewControllerTest.java View File

@@ -53,6 +53,11 @@ public class ViewControllerTest extends BaseTest {
53 53
             protected FrameLayout createView() {
54 54
                 return otherView;
55 55
             }
56
+
57
+            @Override
58
+            public void sendOnNavigationButtonPressed(String buttonId) {
59
+
60
+            }
56 61
         };
57 62
         assertThat(myController.getView()).isEqualTo(otherView);
58 63
     }

+ 52
- 2
lib/android/app/src/test/java/com/reactnativenavigation/views/TopBarTest.java View File

@@ -1,12 +1,20 @@
1 1
 package com.reactnativenavigation.views;
2 2
 
3
+import android.util.Log;
4
+import android.view.MenuItem;
5
+
3 6
 import com.reactnativenavigation.BaseTest;
4 7
 import com.reactnativenavigation.anim.TopBarAnimator;
8
+import com.reactnativenavigation.parse.Button;
9
+import com.reactnativenavigation.parse.Text;
5 10
 import com.reactnativenavigation.parse.params.Bool;
6 11
 import com.reactnativenavigation.parse.params.NullBool;
12
+import com.reactnativenavigation.utils.TitleBarHelper;
7 13
 
8 14
 import org.junit.Test;
9 15
 
16
+import java.util.ArrayList;
17
+
10 18
 import static org.assertj.core.api.Java6Assertions.assertThat;
11 19
 import static org.mockito.Mockito.spy;
12 20
 import static org.mockito.Mockito.times;
@@ -16,16 +24,48 @@ public class TopBarTest extends BaseTest {
16 24
 
17 25
     private TopBar uut;
18 26
     private TopBarAnimator animator;
27
+    private ArrayList<Button> leftButton;
28
+    private ArrayList<Button> rightButtons;
29
+    private TitleBarButton.OnClickListener onClickListener;
19 30
 
20 31
     @Override
21 32
     public void beforeEach() {
22
-        StackLayout parent = new StackLayout(newActivity());
23
-        uut = new TopBar(newActivity(), buttonId -> {}, parent);
33
+        onClickListener = spy(new TitleBarButton.OnClickListener() {
34
+            @Override
35
+            public void onPress(String buttonId) {
36
+                Log.i("TopBarTest", "onPress: " + buttonId);
37
+            }
38
+        });
39
+        StackLayout parent = new StackLayout(newActivity(), this.onClickListener);
40
+        uut = new TopBar(newActivity(), this.onClickListener, parent);
24 41
         animator = spy(new TopBarAnimator(uut));
25 42
         uut.setAnimator(animator);
43
+        leftButton = createLeftButton();
44
+        rightButtons = createRightButtons();
26 45
         parent.addView(uut);
27 46
     }
28 47
 
48
+    private ArrayList<Button> createLeftButton() {
49
+        ArrayList<Button> result = new ArrayList<>();
50
+        Button leftButton = new Button();
51
+        leftButton.id = "leftButton";
52
+        leftButton.title = new Text("");
53
+        result.add(spy(leftButton));
54
+        return result;
55
+    }
56
+
57
+    private ArrayList<Button> createRightButtons() {
58
+        ArrayList<Button> result = new ArrayList<>();
59
+        for (int i = 0; i < 2; i++) {
60
+            Button button = new Button();
61
+            button.id = "rightButtons" + i;
62
+            button.title = new Text("btn" + i);
63
+            button.showAsAction = MenuItem.SHOW_AS_ACTION_ALWAYS;
64
+            result.add(spy(button));
65
+        }
66
+        return result;
67
+    }
68
+
29 69
     @Test
30 70
     public void title() throws Exception {
31 71
         assertThat(uut.getTitle()).isEmpty();
@@ -45,4 +85,14 @@ public class TopBarTest extends BaseTest {
45 85
         uut.show(new NullBool());
46 86
         verify(animator, times(1)).show();
47 87
     }
88
+
89
+    @Test
90
+    public void button_TitleBarButtonOnClickInvoked() throws Exception {
91
+        uut.setButtons(new ArrayList<>(), rightButtons);
92
+        for (int i = 0; i < rightButtons.size(); i++) {
93
+            Button rightButton = rightButtons.get(i);
94
+            TitleBarHelper.getRightButton(uut.getTitleBar(), i).callOnClick();
95
+            verify(onClickListener, times(1)).onPress(rightButton.id);
96
+        }
97
+    }
48 98
 }