|
@@ -1,7 +1,12 @@
|
1
|
1
|
package com.reactnativenavigation.views;
|
2
|
2
|
|
3
|
3
|
import android.os.Bundle;
|
|
4
|
+import android.util.Log;
|
|
5
|
+import android.view.View;
|
|
6
|
+import android.view.ViewGroup;
|
|
7
|
+import android.view.ViewTreeObserver;
|
4
|
8
|
import android.widget.FrameLayout;
|
|
9
|
+import android.widget.ScrollView;
|
5
|
10
|
|
6
|
11
|
import com.facebook.react.ReactInstanceManager;
|
7
|
12
|
import com.facebook.react.ReactRootView;
|
|
@@ -14,8 +19,55 @@ import com.reactnativenavigation.utils.ReflectionUtils;
|
14
|
19
|
* Created by guyc on 10/03/16.
|
15
|
20
|
*/
|
16
|
21
|
public class RctView extends FrameLayout {
|
17
|
|
-
|
|
22
|
+ private static final String TAG = "RctView";
|
18
|
23
|
private ReactRootView mReactRootView;
|
|
24
|
+ private ScrollView mScrollView;
|
|
25
|
+ private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() {
|
|
26
|
+ @Override
|
|
27
|
+ public void onScrollChanged() {
|
|
28
|
+ if (mScrollView.getViewTreeObserver().isAlive()) {
|
|
29
|
+ Log.i(TAG, "onScrollChanged: " + mScrollView.getScrollY());
|
|
30
|
+ }
|
|
31
|
+ }
|
|
32
|
+ };
|
|
33
|
+ private boolean mIsScrollEventListenerRegistered = false;
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+ private final View.OnAttachStateChangeListener mStateChangeListener =
|
|
37
|
+ new View.OnAttachStateChangeListener() {
|
|
38
|
+ @Override
|
|
39
|
+ public void onViewAttachedToWindow(View v) {
|
|
40
|
+ Log.d(TAG, "onViewAttachedToWindow " + v.getClass());
|
|
41
|
+ mScrollView = getScrollView((ViewGroup) getParent());
|
|
42
|
+
|
|
43
|
+ if (mScrollView != null && !mIsScrollEventListenerRegistered) {
|
|
44
|
+ Log.i(TAG, "setting scroll listener");
|
|
45
|
+ addScrollListener();
|
|
46
|
+ } else {
|
|
47
|
+ Log.v(TAG, "doing nothing");
|
|
48
|
+ }
|
|
49
|
+ }
|
|
50
|
+
|
|
51
|
+ @Override
|
|
52
|
+ public void onViewDetachedFromWindow(final View detachedView) {
|
|
53
|
+ Log.d(TAG, "onViewDetachedFromWindow. Removing scrollChangedListener");
|
|
54
|
+ removeScrollListener();
|
|
55
|
+
|
|
56
|
+ post(new Runnable() {
|
|
57
|
+ @Override
|
|
58
|
+ public void run() {
|
|
59
|
+ mScrollView = getScrollView((ViewGroup) getParent());
|
|
60
|
+ if (mScrollView != null && !mIsScrollEventListenerRegistered) {
|
|
61
|
+ Log.i(TAG, "run: setting scroll listener");
|
|
62
|
+ mIsScrollEventListenerRegistered = true;
|
|
63
|
+ addScrollListener();
|
|
64
|
+ } else {
|
|
65
|
+ Log.v(TAG, "doing nothing");
|
|
66
|
+ }
|
|
67
|
+ }
|
|
68
|
+ });
|
|
69
|
+ }
|
|
70
|
+ };
|
19
|
71
|
|
20
|
72
|
/**
|
21
|
73
|
* Interface used to run some code when the {@link ReactRootView} is visible.
|
|
@@ -28,12 +80,26 @@ public class RctView extends FrameLayout {
|
28
|
80
|
}
|
29
|
81
|
|
30
|
82
|
@SuppressWarnings("unchecked")
|
31
|
|
- public RctView(BaseReactActivity ctx, ReactInstanceManager rctInstanceManager, Screen screen,
|
|
83
|
+ public RctView(BaseReactActivity ctx, ReactInstanceManager rctInstanceManager, final Screen screen,
|
32
|
84
|
final OnDisplayedListener onDisplayedListener) {
|
33
|
85
|
super(ctx);
|
34
|
86
|
setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
35
|
87
|
|
36
|
|
- mReactRootView = new RnnReactRootView(ctx, onDisplayedListener);
|
|
88
|
+ OnDisplayedListener onDisplayedListenerInternal = onDisplayedListener;
|
|
89
|
+ if (screen.bottomTabsHiddenOnScroll) {
|
|
90
|
+ onDisplayedListenerInternal = new OnDisplayedListener() {
|
|
91
|
+ @Override
|
|
92
|
+ public void onDisplayed() {
|
|
93
|
+ if (onDisplayedListener != null) {
|
|
94
|
+ onDisplayedListener.onDisplayed();
|
|
95
|
+ }
|
|
96
|
+
|
|
97
|
+ setupScrollViewWithBottomTabs();
|
|
98
|
+ }
|
|
99
|
+ };
|
|
100
|
+ }
|
|
101
|
+
|
|
102
|
+ mReactRootView = new RnnReactRootView(ctx, onDisplayedListenerInternal);
|
37
|
103
|
mReactRootView.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
38
|
104
|
|
39
|
105
|
String componentName = screen.screenId;
|
|
@@ -50,12 +116,49 @@ public class RctView extends FrameLayout {
|
50
|
116
|
addView(mReactRootView);
|
51
|
117
|
}
|
52
|
118
|
|
|
119
|
+ private void setupScrollViewWithBottomTabs() {
|
|
120
|
+ mScrollView = getScrollView((ViewGroup) getParent());
|
|
121
|
+ if (mScrollView != null) {
|
|
122
|
+ attachStateChangeListener(mScrollView);
|
|
123
|
+ addScrollListener();
|
|
124
|
+ }
|
|
125
|
+ }
|
|
126
|
+
|
|
127
|
+ private ScrollView getScrollView(ViewGroup parent) {
|
|
128
|
+ for (int i = 0; i < parent.getChildCount(); i++) {
|
|
129
|
+ View child = parent.getChildAt(i);
|
|
130
|
+
|
|
131
|
+ if (child instanceof ScrollView) {
|
|
132
|
+ return (ScrollView) child;
|
|
133
|
+ }
|
|
134
|
+
|
|
135
|
+ if (child instanceof ViewGroup) {
|
|
136
|
+ return getScrollView((ViewGroup) child);
|
|
137
|
+ }
|
|
138
|
+ }
|
|
139
|
+
|
|
140
|
+ return null;
|
|
141
|
+ }
|
|
142
|
+
|
|
143
|
+ private void attachStateChangeListener(ScrollView scrollView) {
|
|
144
|
+ scrollView.addOnAttachStateChangeListener(mStateChangeListener);
|
|
145
|
+ }
|
|
146
|
+
|
|
147
|
+ private void addScrollListener() {
|
|
148
|
+ mScrollView.getViewTreeObserver().addOnScrollChangedListener(mScrollChangedListener);
|
|
149
|
+ }
|
|
150
|
+
|
|
151
|
+ private void removeScrollListener() {
|
|
152
|
+ mScrollView.getViewTreeObserver().removeOnScrollChangedListener(mScrollChangedListener);
|
|
153
|
+ }
|
|
154
|
+
|
53
|
155
|
/**
|
54
|
156
|
* Must be called before view is removed from screen, but will be added again later. Setting mAttachScheduled
|
55
|
157
|
* to true will prevent the component from getting unmounted once view is detached from screen.
|
56
|
158
|
*/
|
57
|
159
|
public void onTemporallyRemovedFromScreen() {
|
58
|
160
|
// Hack in order to prevent the react view from getting unmounted
|
|
161
|
+
|
59
|
162
|
ReflectionUtils.setField(mReactRootView, "mAttachScheduled", true);
|
60
|
163
|
}
|
61
|
164
|
|