Browse Source

android controller lifecycle #1065

Daniel Zlotin 7 years ago
parent
commit
5810865b61

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

3
 import android.app.Activity;
3
 import android.app.Activity;
4
 import android.support.annotation.Nullable;
4
 import android.support.annotation.Nullable;
5
 import android.view.View;
5
 import android.view.View;
6
+import android.view.ViewTreeObserver;
6
 
7
 
7
 public abstract class ViewController {
8
 public abstract class ViewController {
9
+	public interface LifecycleListener {
10
+		void onCreate(ViewController viewController);
11
+
12
+		void onStart(ViewController viewController);
13
+
14
+		void onStop(ViewController viewController);
15
+
16
+		void onDestroy(ViewController viewController);
17
+	}
18
+
19
+	private enum LifecycleState {
20
+		Created, Started, Stopped, Destroyed
21
+	}
22
+
8
 	private final Activity activity;
23
 	private final Activity activity;
9
 	private View view;
24
 	private View view;
10
 	private StackController stackController;
25
 	private StackController stackController;
26
+	private LifecycleState lifecycleState;
27
+	private LifecycleListener lifecycleListener;
11
 
28
 
12
 	public ViewController(Activity activity) {
29
 	public ViewController(Activity activity) {
13
 		this.activity = activity;
30
 		this.activity = activity;
34
 
51
 
35
 	public View getView() {
52
 	public View getView() {
36
 		if (view == null) {
53
 		if (view == null) {
37
-			view = onCreateView();
54
+			view = createView();
55
+		}
56
+		return view;
57
+	}
58
+
59
+	public void setLifecycleListener(LifecycleListener lifecycleListener) {
60
+		this.lifecycleListener = lifecycleListener;
61
+	}
62
+
63
+	private View createView() {
64
+		View view = onCreateView();
65
+		lifecycleState = LifecycleState.Created;
66
+		view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
67
+			@Override
68
+			public boolean onPreDraw() {
69
+				if (lifecycleListener != null) {
70
+					if (lifecycleState != LifecycleState.Started) {
71
+						lifecycleState = LifecycleState.Started;
72
+						lifecycleListener.onStart(ViewController.this);
73
+					}
74
+				}
75
+				return true;
76
+			}
77
+		});
78
+		if (lifecycleListener != null) {
79
+			lifecycleListener.onCreate(this);
38
 		}
80
 		}
39
 		return view;
81
 		return view;
40
 	}
82
 	}

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

9
 import org.junit.Test;
9
 import org.junit.Test;
10
 
10
 
11
 import static org.assertj.core.api.Java6Assertions.assertThat;
11
 import static org.assertj.core.api.Java6Assertions.assertThat;
12
+import static org.mockito.Mockito.mock;
13
+import static org.mockito.Mockito.times;
14
+import static org.mockito.Mockito.verify;
15
+import static org.mockito.Mockito.verifyZeroInteractions;
12
 
16
 
13
 public class ViewControllerTest extends BaseTest {
17
 public class ViewControllerTest extends BaseTest {
14
 
18
 
56
 	public void handleBackDefaultFalse() throws Exception {
60
 	public void handleBackDefaultFalse() throws Exception {
57
 		assertThat(uut.handleBack()).isFalse();
61
 		assertThat(uut.handleBack()).isFalse();
58
 	}
62
 	}
63
+
64
+	public static class LifecycleTest extends BaseTest {
65
+		private ViewController controller;
66
+		private ViewController.LifecycleListener uut;
67
+
68
+		@Override
69
+		public void beforeEach() {
70
+			super.beforeEach();
71
+			Activity activity = newActivity();
72
+			controller = new SimpleViewController(activity, "controller");
73
+			uut = mock(ViewController.LifecycleListener.class);
74
+			controller.setLifecycleListener(uut);
75
+		}
76
+
77
+		@Test
78
+		public void onCreateView_CalledAsSoonAsPossible() throws Exception {
79
+			verifyZeroInteractions(uut);
80
+			controller.getView();
81
+			verify(uut, times(1)).onCreate(controller);
82
+		}
83
+
84
+		@Test
85
+		public void onStart_CalledBeforeFirstDraw() throws Exception {
86
+			verifyZeroInteractions(uut);
87
+			controller.getView().getViewTreeObserver().dispatchOnPreDraw();
88
+			controller.getView().getViewTreeObserver().dispatchOnPreDraw();
89
+			verify(uut, times(1)).onStart(controller);
90
+		}
91
+	}
92
+
59
 }
93
 }