瀏覽代碼

Dispatch visibility events for SideMenu screens

Visibility events for both left and right SideMenu screens were not dispatched due to how the native
DrawerLayout is implemented.
Fixes #4303
Guy Carmeli 6 年之前
父節點
當前提交
daa5139682

+ 4
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/SideMenuOptions.java 查看文件

@@ -11,6 +11,7 @@ import org.json.JSONObject;
11 11
 
12 12
 public class SideMenuOptions {
13 13
     public Bool visible = new NullBool();
14
+    public Bool animate = new NullBool();
14 15
     public Bool enabled = new NullBool();
15 16
     public Number height = new NullNumber();
16 17
     public Number width = new NullNumber();
@@ -20,6 +21,7 @@ public class SideMenuOptions {
20 21
         if (json == null) return options;
21 22
 
22 23
         options.visible = BoolParser.parse(json, "visible");
24
+        options.animate = BoolParser.parse(json, "animate");
23 25
         options.enabled = BoolParser.parse(json, "enabled");
24 26
         options.height = NumberParser.parse(json, "height");
25 27
         options.width = NumberParser.parse(json, "width");
@@ -29,6 +31,7 @@ public class SideMenuOptions {
29 31
 
30 32
     public void mergeWith(SideMenuOptions other) {
31 33
         if (other.visible.hasValue()) visible = other.visible;
34
+        if (other.animate.hasValue()) animate = other.animate;
32 35
         if (other.enabled.hasValue()) enabled = other.enabled;
33 36
         if (other.height.hasValue()) height = other.height;
34 37
         if (other.width.hasValue()) width = other.width;
@@ -36,6 +39,7 @@ public class SideMenuOptions {
36 39
 
37 40
     public void mergeWithDefault(SideMenuOptions defaultOptions) {
38 41
         if (!visible.hasValue()) visible = defaultOptions.visible;
42
+        if (!animate.hasValue()) animate = defaultOptions.animate;
39 43
         if (!enabled.hasValue()) enabled = defaultOptions.enabled;
40 44
         if (!height.hasValue()) height = defaultOptions.height;
41 45
         if (!width.hasValue()) width = defaultOptions.width;

+ 4
- 4
lib/android/app/src/main/java/com/reactnativenavigation/presentation/SideMenuPresenter.java 查看文件

@@ -51,15 +51,15 @@ public class SideMenuPresenter {
51 51
 
52 52
     private void mergeVisibility(SideMenuRootOptions options) {
53 53
         if (options.left.visible.isTrue()) {
54
-            sideMenu.openDrawer(Gravity.LEFT);
54
+            sideMenu.openDrawer(Gravity.LEFT, options.left.animate.get(true));
55 55
         } else if (options.left.visible.isFalse()) {
56
-            sideMenu.closeDrawer(Gravity.LEFT);
56
+            sideMenu.closeDrawer(Gravity.LEFT, options.left.animate.get(true));
57 57
         }
58 58
 
59 59
         if (options.right.visible.isTrue()) {
60
-            sideMenu.openDrawer(Gravity.RIGHT);
60
+            sideMenu.openDrawer(Gravity.RIGHT, options.right.animate.get(true));
61 61
         } else if (options.right.visible.isFalse()) {
62
-            sideMenu.closeDrawer(Gravity.RIGHT);
62
+            sideMenu.closeDrawer(Gravity.RIGHT, options.right.animate.get(true));
63 63
         }
64 64
     }
65 65
 

+ 22
- 1
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/sidemenu/SideMenuController.java 查看文件

@@ -24,7 +24,7 @@ import java.util.Collection;
24 24
 
25 25
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
26 26
 
27
-public class SideMenuController extends ParentController<DrawerLayout> {
27
+public class SideMenuController extends ParentController<DrawerLayout> implements DrawerLayout.DrawerListener {
28 28
 
29 29
 	private ViewController center;
30 30
 	private ViewController left;
@@ -51,6 +51,7 @@ public class SideMenuController extends ParentController<DrawerLayout> {
51 51
 	protected DrawerLayout createView() {
52 52
         DrawerLayout sideMenu = new DrawerLayout(getActivity());
53 53
         presenter.bindView(sideMenu);
54
+        sideMenu.addDrawerListener(this);
54 55
         return sideMenu;
55 56
 	}
56 57
 
@@ -102,6 +103,16 @@ public class SideMenuController extends ParentController<DrawerLayout> {
102 103
         return options;
103 104
     }
104 105
 
106
+    @Override
107
+    public void onDrawerOpened(@NonNull View drawerView) {
108
+        (left != null && drawerView.equals(left.getView()) ? left : right).onViewAppeared();
109
+    }
110
+
111
+    @Override
112
+    public void onDrawerClosed(@NonNull View drawerView) {
113
+        (left != null && drawerView.equals(left.getView()) ? left : right).onViewDisappear();
114
+    }
115
+
105 116
     @Override
106 117
     public boolean handleBack(CommandListener listener) {
107 118
         return presenter.handleBack() || center.handleBack(listener) || super.handleBack(listener);
@@ -142,4 +153,14 @@ public class SideMenuController extends ParentController<DrawerLayout> {
142 153
         }
143 154
         return height;
144 155
     }
156
+
157
+    @Override
158
+    public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
159
+
160
+    }
161
+
162
+    @Override
163
+    public void onDrawerStateChanged(int newState) {
164
+
165
+    }
145 166
 }

+ 66
- 2
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/sidemenu/SideMenuControllerTest.java 查看文件

@@ -198,7 +198,7 @@ public class SideMenuControllerTest extends BaseTest {
198 198
         assertThat(uut.handleBack(new CommandListenerAdapter())).isFalse();
199 199
         verify(center, times(1)).handleBack(any());
200 200
 
201
-        uut.mergeOptions(SideMenuTestHelper.LEFT_OPEN);
201
+        openLeftMenu();
202 202
         assertThat(uut.handleBack(new CommandListenerAdapter())).isTrue();
203 203
         verify(center, times(1)).handleBack(any());
204 204
     }
@@ -209,8 +209,72 @@ public class SideMenuControllerTest extends BaseTest {
209 209
         assertThat(uut.handleBack(new CommandListenerAdapter())).isFalse();
210 210
         verify(center, times(1)).handleBack(any());
211 211
 
212
-        uut.mergeOptions(SideMenuTestHelper.RIGHT_OPEN);
212
+        openRightMenu();
213 213
         assertThat(uut.handleBack(new CommandListenerAdapter())).isTrue();
214 214
         verify(center, times(1)).handleBack(any());
215 215
     }
216
+
217
+    @Test
218
+    public void leftMenuOpen_visibilityEventsAreEmitted() {
219
+        ViewController spy = spy(left);
220
+        uut.setLeftController(spy);
221
+        activity.setContentView(uut.getView());
222
+
223
+        assertThat(uut.getView().isDrawerOpen(Gravity.LEFT)).isFalse();
224
+        verify(spy, times(0)).onViewAppeared();
225
+
226
+        openLeftMenu();
227
+        assertThat(uut.getView().isDrawerOpen(Gravity.LEFT)).isTrue();
228
+        verify(spy).onViewAppeared();
229
+
230
+        closeLeft();
231
+        assertThat(uut.getView().isDrawerOpen(Gravity.LEFT)).isFalse();
232
+        verify(spy).onViewDisappear();
233
+    }
234
+
235
+    @Test
236
+    public void rightMenuOpen_visibilityEventsAreEmitted() {
237
+        ViewController spy = spy(right);
238
+        uut.setRightController(spy);
239
+        activity.setContentView(uut.getView());
240
+
241
+        assertThat(uut.getView().isDrawerOpen(Gravity.RIGHT)).isFalse();
242
+        verify(spy, times(0)).onViewAppeared();
243
+
244
+        openRightMenu();
245
+        assertThat(uut.getView().isDrawerOpen(Gravity.RIGHT)).isTrue();
246
+        verify(spy).onViewAppeared();
247
+
248
+        closeRightMenu();
249
+        assertThat(uut.getView().isDrawerOpen(Gravity.RIGHT)).isFalse();
250
+        verify(spy).onViewDisappear();
251
+    }
252
+
253
+    private void openLeftMenu() {
254
+        Options options = new Options();
255
+        options.sideMenuRootOptions.left.visible = new Bool(true);
256
+        options.sideMenuRootOptions.left.animate = new Bool(false);
257
+        uut.mergeOptions(options);
258
+    }
259
+
260
+    private void openRightMenu() {
261
+        Options options = new Options();
262
+        options.sideMenuRootOptions.right.visible = new Bool(true);
263
+        options.sideMenuRootOptions.right.animate = new Bool(false);
264
+        uut.mergeOptions(options);
265
+    }
266
+
267
+    private void closeLeft() {
268
+        Options options = new Options();
269
+        options.sideMenuRootOptions.left.visible = new Bool(false);
270
+        options.sideMenuRootOptions.left.animate = new Bool(false);
271
+        uut.mergeOptions(options);
272
+    }
273
+
274
+    private void closeRightMenu() {
275
+        Options options = new Options();
276
+        options.sideMenuRootOptions.right.visible = new Bool(false);
277
+        options.sideMenuRootOptions.right.animate = new Bool(false);
278
+        uut.mergeOptions(options);
279
+    }
216 280
 }

+ 0
- 14
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/sidemenu/SideMenuTestHelper.java 查看文件

@@ -1,14 +0,0 @@
1
-package com.reactnativenavigation.viewcontrollers.sidemenu;
2
-
3
-import com.reactnativenavigation.parse.Options;
4
-import com.reactnativenavigation.parse.params.Bool;
5
-
6
-public class SideMenuTestHelper {
7
-    static final Options LEFT_OPEN = new Options();
8
-    static final Options RIGHT_OPEN = new Options();
9
-
10
-    static {
11
-        LEFT_OPEN.sideMenuRootOptions.left.visible = new Bool(true);
12
-        RIGHT_OPEN.sideMenuRootOptions.right.visible = new Bool(true);
13
-    }
14
-}

+ 13
- 0
playground/src/screens/SideMenuScreen.js 查看文件

@@ -8,6 +8,19 @@ const testIDs = require('../testIDs');
8 8
 
9 9
 class SideMenuScreen extends Component {
10 10
 
11
+  constructor(props) {
12
+    super(props);
13
+    Navigation.events().bindComponent(this);
14
+  }
15
+
16
+  componentDidAppear() {
17
+    console.log('RNN', `SMS.componentDidAppear ${this.props.side}`);
18
+  }
19
+
20
+  componentDidDisappear() {
21
+    console.log('RNN', `SMS.componentDidDisappear ${this.props.side}`);
22
+  }
23
+
11 24
   render() {
12 25
     const testID = this.props.side === 'left' ? testIDs.HIDE_LEFT_SIDE_MENU_BUTTON : testIDs.HIDE_RIGHT_SIDE_MENU_BUTTON;
13 26
     return (