Browse Source

handleBack in navigator and bottomtabs

Daniel Zlotin 7 years ago
parent
commit
83ec0b816b

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

15
 	private final String name;
15
 	private final String name;
16
 	private final ReactInstanceManager reactInstanceManager;
16
 	private final ReactInstanceManager reactInstanceManager;
17
 	private boolean attachedToReactInstance = false;
17
 	private boolean attachedToReactInstance = false;
18
+	private ReactRootView reactRootView;
18
 
19
 
19
 	public ReactRootViewController(final Activity activity, final String id, final String name, final ReactInstanceManager reactInstanceManager) {
20
 	public ReactRootViewController(final Activity activity, final String id, final String name, final ReactInstanceManager reactInstanceManager) {
20
 		super(activity, id);
21
 		super(activity, id);
22
 		this.reactInstanceManager = reactInstanceManager;
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
 	@Override
33
 	@Override
31
 	public void onAppear() {
34
 	public void onAppear() {
47
 	@NonNull
50
 	@NonNull
48
 	@Override
51
 	@Override
49
 	protected View createView() {
52
 	protected View createView() {
50
-		ReactRootView reactRootView = new ReactRootView(getActivity());
53
+		reactRootView = new ReactRootView(getActivity());
51
 		Bundle opts = new Bundle();
54
 		Bundle opts = new Bundle();
52
 		opts.putString("id", getId());
55
 		opts.putString("id", getId());
53
 		reactRootView.startReactApplication(this.reactInstanceManager, this.name, opts);
56
 		reactRootView.startReactApplication(this.reactInstanceManager, this.name, opts);

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

44
 		return root;
44
 		return root;
45
 	}
45
 	}
46
 
46
 
47
+	@Override
48
+	public boolean handleBack() {
49
+		return !tabs.isEmpty() && tabs.get(selectedIndex).handleBack();
50
+	}
51
+
47
 	@Override
52
 	@Override
48
 	public boolean onNavigationItemSelected(@NonNull final MenuItem item) {
53
 	public boolean onNavigationItemSelected(@NonNull final MenuItem item) {
49
 		selectTabAtIndex(item.getItemId());
54
 		selectTabAtIndex(item.getItemId());

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

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

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

56
 			@Override
56
 			@Override
57
 			public void run() {
57
 			public void run() {
58
 				getView().removeView(poppedTop.getView());
58
 				getView().removeView(poppedTop.getView());
59
-				poppedTop.destroy();
59
+				poppedTop.onDestroy();
60
 			}
60
 			}
61
 		});
61
 		});
62
 	}
62
 	}
66
 			pop();
66
 			pop();
67
 		} else {
67
 		} else {
68
 			stack.remove(childController.getId());
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 View File

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
 		view = null;
76
 		view = null;
77
 	}
77
 	}
78
 
78
 

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

16
 import java.util.List;
16
 import java.util.List;
17
 
17
 
18
 import static org.assertj.core.api.Java6Assertions.assertThat;
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
 public class BottomTabsControllerTest extends BaseTest {
24
 public class BottomTabsControllerTest extends BaseTest {
21
 
25
 
92
 		assertThat(uut.findControllerById(child1.getId())).isEqualTo(child1);
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
 	@NonNull
116
 	@NonNull
96
 	private List<ViewController> createTabs() {
117
 	private List<ViewController> createTabs() {
97
 		return Arrays.asList(child1, child2, child3, child4, child5);
118
 		return Arrays.asList(child1, child2, child3, child4, child5);

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

15
 import java.util.Arrays;
15
 import java.util.Arrays;
16
 
16
 
17
 import static org.assertj.core.api.Java6Assertions.assertThat;
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
 public class NavigatorTest extends BaseTest {
23
 public class NavigatorTest extends BaseTest {
20
 	private Activity activity;
24
 	private Activity activity;
194
 		assertThat(stack2.getChildControllers()).containsOnly(child2);
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
 	@NonNull
211
 	@NonNull
198
 	private BottomTabsController newTabs() {
212
 	private BottomTabsController newTabs() {
199
 		return new BottomTabsController(activity, "tabsController");
213
 		return new BottomTabsController(activity, "tabsController");

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

250
 		uut.push(child2);
250
 		uut.push(child2);
251
 		uut.push(child3);
251
 		uut.push(child3);
252
 
252
 
253
-		verify(child3, times(0)).destroy();
253
+		verify(child3, times(0)).onDestroy();
254
 		uut.pop();
254
 		uut.pop();
255
-		verify(child3, times(1)).destroy();
255
+		verify(child3, times(1)).onDestroy();
256
 	}
256
 	}
257
 
257
 
258
 	@Test
258
 	@Test
264
 		uut.push(child2);
264
 		uut.push(child2);
265
 		uut.push(child3);
265
 		uut.push(child3);
266
 
266
 
267
-		verify(child2, times(0)).destroy();
267
+		verify(child2, times(0)).onDestroy();
268
 		uut.popSpecific(child2);
268
 		uut.popSpecific(child2);
269
-		verify(child2, times(1)).destroy();
269
+		verify(child2, times(1)).onDestroy();
270
 	}
270
 	}
271
 
271
 
272
 	@Test
272
 	@Test
278
 		uut.push(child2);
278
 		uut.push(child2);
279
 		uut.push(child3);
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
 		uut.popTo(child1);
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
 	private void assertHasSingleChildViewOfController(ViewController childController) {
288
 	private void assertHasSingleChildViewOfController(ViewController childController) {

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

11
 import org.junit.Test;
11
 import org.junit.Test;
12
 import org.robolectric.Shadows;
12
 import org.robolectric.Shadows;
13
 
13
 
14
+import java.lang.reflect.Field;
15
+
14
 import static org.assertj.core.api.Java6Assertions.assertThat;
16
 import static org.assertj.core.api.Java6Assertions.assertThat;
15
 import static org.mockito.Mockito.mock;
17
 import static org.mockito.Mockito.mock;
16
 import static org.mockito.Mockito.spy;
18
 import static org.mockito.Mockito.spy;
135
 		spy.getView().getViewTreeObserver().dispatchOnGlobalLayout();
137
 		spy.getView().getViewTreeObserver().dispatchOnGlobalLayout();
136
 		verify(spy, times(1)).onDisappear();
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