소스 검색

Setup ScrollView with BottomNavigation in RctView

Guy Carmeli 8 년 전
부모
커밋
044e4da36c

+ 1
- 98
android/app/src/main/java/com/reactnativenavigation/activities/BottomTabActivity.java 파일 보기

@@ -5,11 +5,7 @@ import android.graphics.drawable.Drawable;
5 5
 import android.os.AsyncTask;
6 6
 import android.os.Bundle;
7 7
 import android.support.design.widget.CoordinatorLayout;
8
-import android.util.Log;
9 8
 import android.view.View;
10
-import android.view.ViewGroup;
11
-import android.view.ViewTreeObserver;
12
-import android.widget.ScrollView;
13 9
 
14 10
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
15 11
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem;
@@ -20,7 +16,6 @@ import com.reactnativenavigation.core.objects.Drawer;
20 16
 import com.reactnativenavigation.core.objects.Screen;
21 17
 import com.reactnativenavigation.utils.StyleHelper;
22 18
 import com.reactnativenavigation.views.BottomNavigation;
23
-import com.reactnativenavigation.views.RctView;
24 19
 import com.reactnativenavigation.views.RnnToolBar;
25 20
 import com.reactnativenavigation.views.ScreenStack;
26 21
 
@@ -48,33 +43,6 @@ public class BottomTabActivity extends BaseReactActivity implements AHBottomNavi
48 43
     private ArrayList<ScreenStack> mScreenStacks;
49 44
     private int mCurrentStackPosition = -1;
50 45
 
51
-    private ScrollView mScrollView;
52
-    private ViewTreeObserver.OnScrollChangedListener mScrollChangedListener;
53
-    private final View.OnAttachStateChangeListener mScrollViewStateChangeListener =
54
-            new View.OnAttachStateChangeListener() {
55
-                @Override
56
-                public void onViewAttachedToWindow(View v) {
57
-
58
-                }
59
-
60
-                @Override
61
-                public void onViewDetachedFromWindow(View detachedScrollView) {
62
-                    detachedScrollView.getViewTreeObserver().removeOnScrollChangedListener(mScrollChangedListener);
63
-                    detachedScrollView.removeOnAttachStateChangeListener(this);
64
-
65
-                    mContentFrame.post(new Runnable() {
66
-                        @Override
67
-                        public void run() {
68
-                            mScrollView = getScrollView(mContentFrame);
69
-                            if (mScrollView != null) {
70
-                                mScrollView.addOnAttachStateChangeListener(mScrollViewStateChangeListener);
71
-                                addScrollListener(mScrollView);
72
-                            }
73
-                        }
74
-                    });
75
-                }
76
-            };
77
-
78 46
     @Override
79 47
     protected void handleOnCreate() {
80 48
         super.handleOnCreate();
@@ -99,18 +67,6 @@ public class BottomTabActivity extends BaseReactActivity implements AHBottomNavi
99 67
                 setupToolbar(screens);
100 68
             }
101 69
         });
102
-
103
-        mContentFrame.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
104
-            @Override
105
-            public void onChildViewAdded(View parent, View child) {
106
-                Log.i(TAG, "onChildViewAdded: " + child.getClass());
107
-            }
108
-
109
-            @Override
110
-            public void onChildViewRemoved(View parent, View child) {
111
-                Log.d(TAG, "onChildViewRemoved: " + child.getClass());
112
-            }
113
-        });
114 70
     }
115 71
 
116 72
     private void setupPages(ArrayList<Screen> screens) {
@@ -124,48 +80,6 @@ public class BottomTabActivity extends BaseReactActivity implements AHBottomNavi
124 80
         StyleHelper.updateStyles(mToolbar, initialScreen);
125 81
     }
126 82
 
127
-    private void setupBottomTabs(Screen initialScreen) {
128
-        if (initialScreen.bottomTabsHiddenOnScroll) {
129
-            mScrollView = getScrollView(mContentFrame);
130
-            if (mScrollView != null) {
131
-                attachStateChangeListener(mScrollView);
132
-                addScrollListener(mScrollView);
133
-            }
134
-        }
135
-    }
136
-
137
-    private void attachStateChangeListener(ScrollView scrollView) {
138
-        scrollView.addOnAttachStateChangeListener(mScrollViewStateChangeListener);
139
-    }
140
-
141
-    private void addScrollListener(final ScrollView scrollView) {
142
-        mScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() {
143
-            @Override
144
-            public void onScrollChanged() {
145
-                if (scrollView.getViewTreeObserver().isAlive()) {
146
-                    Log.i(TAG, "onScrollChanged: " + scrollView.getScrollY());
147
-                }
148
-            }
149
-        };
150
-        scrollView.getViewTreeObserver().addOnScrollChangedListener(mScrollChangedListener);
151
-    }
152
-
153
-    private ScrollView getScrollView(ViewGroup parent) {
154
-        for (int i = 0; i < parent.getChildCount(); i++) {
155
-            View child = parent.getChildAt(i);
156
-
157
-            if (child instanceof ScrollView) {
158
-                return (ScrollView) child;
159
-            }
160
-
161
-            if (child instanceof ViewGroup) {
162
-                return getScrollView((ViewGroup) child);
163
-            }
164
-        }
165
-
166
-        return null;
167
-    }
168
-
169 83
     @Override
170 84
     protected void onResume() {
171 85
         super.onResume();
@@ -385,18 +299,7 @@ public class BottomTabActivity extends BaseReactActivity implements AHBottomNavi
385 299
         for (int i = 0; i < screens.size(); i++) {
386 300
             final Screen screen = screens.get(i);
387 301
             ScreenStack stack = new ScreenStack(this);
388
-
389
-            if (i == 0) {
390
-                stack.push(screen, new RctView.OnDisplayedListener() {
391
-                    @Override
392
-                    public void onDisplayed() {
393
-                        setupBottomTabs(screen);
394
-                    }
395
-                });
396
-            } else {
397
-                stack.push(screen);
398
-            }
399
-
302
+            stack.push(screen);
400 303
             mScreenStacks.add(stack);
401 304
             AHBottomNavigationItem item = new AHBottomNavigationItem(screen.label, icons.get(screen), Color.GRAY);
402 305
             mBottomNavigation.addItem(item);

+ 106
- 3
android/app/src/main/java/com/reactnativenavigation/views/RctView.java 파일 보기

@@ -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