ソースを参照

handleBack in navigator and bottomtabs

Daniel Zlotin 7 年 前
コミット
83ec0b816b

+ 8
- 5
lib/android/app/src/main/java/com/reactnativenavigation/layout/ReactRootViewController.java ファイルの表示

@@ -15,6 +15,7 @@ public class ReactRootViewController extends ViewController {
15 15
 	private final String name;
16 16
 	private final ReactInstanceManager reactInstanceManager;
17 17
 	private boolean attachedToReactInstance = false;
18
+	private ReactRootView reactRootView;
18 19
 
19 20
 	public ReactRootViewController(final Activity activity, final String id, final String name, final ReactInstanceManager reactInstanceManager) {
20 21
 		super(activity, id);
@@ -22,10 +23,12 @@ public class ReactRootViewController extends ViewController {
22 23
 		this.reactInstanceManager = reactInstanceManager;
23 24
 	}
24 25
 
25
-//	@Override
26
-//	public void destroy() {
27
-//		reactRootView.unmountReactApplication();
28
-//	}
26
+	@Override
27
+	public void onDestroy() {
28
+		super.onDestroy();
29
+		if (reactRootView != null) reactRootView.unmountReactApplication();
30
+		reactRootView = null;
31
+	}
29 32
 
30 33
 	@Override
31 34
 	public void onAppear() {
@@ -47,7 +50,7 @@ public class ReactRootViewController extends ViewController {
47 50
 	@NonNull
48 51
 	@Override
49 52
 	protected View createView() {
50
-		ReactRootView reactRootView = new ReactRootView(getActivity());
53
+		reactRootView = new ReactRootView(getActivity());
51 54
 		Bundle opts = new Bundle();
52 55
 		opts.putString("id", getId());
53 56
 		reactRootView.startReactApplication(this.reactInstanceManager, this.name, opts);

+ 5
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/BottomTabsController.java ファイルの表示

@@ -44,6 +44,11 @@ public class BottomTabsController extends ParentController implements BottomNavi
44 44
 		return root;
45 45
 	}
46 46
 
47
+	@Override
48
+	public boolean handleBack() {
49
+		return !tabs.isEmpty() && tabs.get(selectedIndex).handleBack();
50
+	}
51
+
47 52
 	@Override
48 53
 	public boolean onNavigationItemSelected(@NonNull final MenuItem item) {
49 54
 		selectTabAtIndex(item.getItemId());

+ 5
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/Navigator.java ファイルの表示

@@ -54,6 +54,11 @@ public class Navigator extends ParentController {
54 54
 		//
55 55
 	}
56 56
 
57
+	@Override
58
+	public boolean handleBack() {
59
+		return root != null && root.handleBack();
60
+	}
61
+
57 62
 	/*
58 63
 	 * Navigation methods
59 64
 	 */

+ 2
- 2
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/StackController.java ファイルの表示

@@ -56,7 +56,7 @@ public class StackController extends ParentController {
56 56
 			@Override
57 57
 			public void run() {
58 58
 				getView().removeView(poppedTop.getView());
59
-				poppedTop.destroy();
59
+				poppedTop.onDestroy();
60 60
 			}
61 61
 		});
62 62
 	}
@@ -66,7 +66,7 @@ public class StackController extends ParentController {
66 66
 			pop();
67 67
 		} else {
68 68
 			stack.remove(childController.getId());
69
-			childController.destroy();
69
+			childController.onDestroy();
70 70
 		}
71 71
 	}
72 72
 

+ 2
- 2
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ViewController.java ファイルの表示

@@ -71,8 +71,8 @@ public abstract class ViewController implements ViewTreeObserver.OnGlobalLayoutL
71 71
 		//
72 72
 	}
73 73
 
74
-	public void destroy() {
75
-		getView().getViewTreeObserver().removeOnGlobalLayoutListener(this);
74
+	public void onDestroy() {
75
+		view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
76 76
 		view = null;
77 77
 	}
78 78
 

+ 21
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/BottomTabsControllerTest.java ファイルの表示

@@ -16,6 +16,10 @@ import java.util.Arrays;
16 16
 import java.util.List;
17 17
 
18 18
 import static org.assertj.core.api.Java6Assertions.assertThat;
19
+import static org.mockito.Mockito.spy;
20
+import static org.mockito.Mockito.times;
21
+import static org.mockito.Mockito.verify;
22
+import static org.mockito.Mockito.when;
19 23
 
20 24
 public class BottomTabsControllerTest extends BaseTest {
21 25
 
@@ -92,6 +96,23 @@ public class BottomTabsControllerTest extends BaseTest {
92 96
 		assertThat(uut.findControllerById(child1.getId())).isEqualTo(child1);
93 97
 	}
94 98
 
99
+	@Test
100
+	public void handleBack_DelegatesToSelectedChild() throws Exception {
101
+		assertThat(uut.handleBack()).isFalse();
102
+
103
+		List<ViewController> tabs = createTabs();
104
+		ViewController spy = spy(tabs.get(2));
105
+		tabs.set(2, spy);
106
+		when(spy.handleBack()).thenReturn(true);
107
+		uut.setTabs(tabs);
108
+
109
+		assertThat(uut.handleBack()).isFalse();
110
+		uut.selectTabAtIndex(2);
111
+		assertThat(uut.handleBack()).isTrue();
112
+
113
+		verify(spy, times(1)).handleBack();
114
+	}
115
+
95 116
 	@NonNull
96 117
 	private List<ViewController> createTabs() {
97 118
 		return Arrays.asList(child1, child2, child3, child4, child5);

+ 14
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/NavigatorTest.java ファイルの表示

@@ -15,6 +15,10 @@ import org.robolectric.Shadows;
15 15
 import java.util.Arrays;
16 16
 
17 17
 import static org.assertj.core.api.Java6Assertions.assertThat;
18
+import static org.mockito.Mockito.spy;
19
+import static org.mockito.Mockito.times;
20
+import static org.mockito.Mockito.verify;
21
+import static org.mockito.Mockito.when;
18 22
 
19 23
 public class NavigatorTest extends BaseTest {
20 24
 	private Activity activity;
@@ -194,6 +198,16 @@ public class NavigatorTest extends BaseTest {
194 198
 		assertThat(stack2.getChildControllers()).containsOnly(child2);
195 199
 	}
196 200
 
201
+	@Test
202
+	public void handleBack_DelegatesToRoot() throws Exception {
203
+		assertThat(uut.handleBack()).isFalse();
204
+		ViewController spy = spy(child1);
205
+		uut.setRoot(spy);
206
+		when(spy.handleBack()).thenReturn(true);
207
+		assertThat(uut.handleBack()).isTrue();
208
+		verify(spy, times(1)).handleBack();
209
+	}
210
+
197 211
 	@NonNull
198 212
 	private BottomTabsController newTabs() {
199 213
 		return new BottomTabsController(activity, "tabsController");

+ 8
- 8
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/StackControllerTest.java ファイルの表示

@@ -250,9 +250,9 @@ public class StackControllerTest extends BaseTest {
250 250
 		uut.push(child2);
251 251
 		uut.push(child3);
252 252
 
253
-		verify(child3, times(0)).destroy();
253
+		verify(child3, times(0)).onDestroy();
254 254
 		uut.pop();
255
-		verify(child3, times(1)).destroy();
255
+		verify(child3, times(1)).onDestroy();
256 256
 	}
257 257
 
258 258
 	@Test
@@ -264,9 +264,9 @@ public class StackControllerTest extends BaseTest {
264 264
 		uut.push(child2);
265 265
 		uut.push(child3);
266 266
 
267
-		verify(child2, times(0)).destroy();
267
+		verify(child2, times(0)).onDestroy();
268 268
 		uut.popSpecific(child2);
269
-		verify(child2, times(1)).destroy();
269
+		verify(child2, times(1)).onDestroy();
270 270
 	}
271 271
 
272 272
 	@Test
@@ -278,11 +278,11 @@ public class StackControllerTest extends BaseTest {
278 278
 		uut.push(child2);
279 279
 		uut.push(child3);
280 280
 
281
-		verify(child2, times(0)).destroy();
282
-		verify(child3, times(0)).destroy();
281
+		verify(child2, times(0)).onDestroy();
282
+		verify(child3, times(0)).onDestroy();
283 283
 		uut.popTo(child1);
284
-		verify(child2, times(1)).destroy();
285
-		verify(child3, times(1)).destroy();
284
+		verify(child2, times(1)).onDestroy();
285
+		verify(child3, times(1)).onDestroy();
286 286
 	}
287 287
 
288 288
 	private void assertHasSingleChildViewOfController(ViewController childController) {

+ 25
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/ViewControllerTest.java ファイルの表示

@@ -11,6 +11,8 @@ import org.assertj.android.api.Assertions;
11 11
 import org.junit.Test;
12 12
 import org.robolectric.Shadows;
13 13
 
14
+import java.lang.reflect.Field;
15
+
14 16
 import static org.assertj.core.api.Java6Assertions.assertThat;
15 17
 import static org.mockito.Mockito.mock;
16 18
 import static org.mockito.Mockito.spy;
@@ -135,5 +137,28 @@ public class ViewControllerTest extends BaseTest {
135 137
 		spy.getView().getViewTreeObserver().dispatchOnGlobalLayout();
136 138
 		verify(spy, times(1)).onDisappear();
137 139
 	}
140
+
141
+	@Test
142
+	public void onDestroy_RemovesGlobalLayoutListener() throws Exception {
143
+		ViewController spy = spy(uut);
144
+		View view = spy.getView();
145
+		Shadows.shadowOf(view).setMyParent(mock(ViewParent.class));
146
+
147
+		spy.onDestroy();
148
+
149
+		Assertions.assertThat(view).isShown();
150
+		view.getViewTreeObserver().dispatchOnGlobalLayout();
151
+		verify(spy, times(0)).onAppear();
152
+		verify(spy, times(0)).onDisappear();
153
+	}
154
+
155
+	@Test
156
+	public void onDestroy_NullifiesTheView() throws Exception {
157
+		assertThat(uut.getView()).isNotNull();
158
+		uut.onDestroy();
159
+		Field field = ViewController.class.getDeclaredField("view");
160
+		field.setAccessible(true);
161
+		assertThat(field.get(uut)).isNull();
162
+	}
138 163
 }
139 164