Quellcode durchsuchen

Find proper ScrollView and detect scroll

Guy Carmeli vor 8 Jahren
Ursprung
Commit
2683e395fd

+ 98
- 4
android/app/src/main/java/com/reactnativenavigation/activities/BottomTabActivity.java Datei anzeigen

5
 import android.os.AsyncTask;
5
 import android.os.AsyncTask;
6
 import android.os.Bundle;
6
 import android.os.Bundle;
7
 import android.support.design.widget.CoordinatorLayout;
7
 import android.support.design.widget.CoordinatorLayout;
8
+import android.util.Log;
8
 import android.view.View;
9
 import android.view.View;
10
+import android.view.ViewGroup;
11
+import android.view.ViewTreeObserver;
12
+import android.widget.ScrollView;
9
 
13
 
10
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
14
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
11
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem;
15
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem;
15
 import com.reactnativenavigation.core.objects.Drawer;
19
 import com.reactnativenavigation.core.objects.Drawer;
16
 import com.reactnativenavigation.core.objects.Screen;
20
 import com.reactnativenavigation.core.objects.Screen;
17
 import com.reactnativenavigation.utils.StyleHelper;
21
 import com.reactnativenavigation.utils.StyleHelper;
22
+import com.reactnativenavigation.views.BottomNavigation;
23
+import com.reactnativenavigation.views.RctView;
18
 import com.reactnativenavigation.views.RnnToolBar;
24
 import com.reactnativenavigation.views.RnnToolBar;
19
 import com.reactnativenavigation.views.ScreenStack;
25
 import com.reactnativenavigation.views.ScreenStack;
20
 
26
 
23
 import java.util.Map;
29
 import java.util.Map;
24
 
30
 
25
 public class BottomTabActivity extends BaseReactActivity implements AHBottomNavigation.OnTabSelectedListener {
31
 public class BottomTabActivity extends BaseReactActivity implements AHBottomNavigation.OnTabSelectedListener {
32
+    private static final String TAG = "BottomTabActivity";
26
     public static final String DRAWER_PARAMS = "drawerParams";
33
     public static final String DRAWER_PARAMS = "drawerParams";
27
     public static final String EXTRA_SCREENS = "extraScreens";
34
     public static final String EXTRA_SCREENS = "extraScreens";
28
 
35
 
36
     private static int DEFAULT_TAB_SELECTED_COLOR = 0xFF0000FF;
43
     private static int DEFAULT_TAB_SELECTED_COLOR = 0xFF0000FF;
37
     private static boolean DEFAULT_TAB_INACTIVE_TITLES = true;
44
     private static boolean DEFAULT_TAB_INACTIVE_TITLES = true;
38
 
45
 
39
-    private AHBottomNavigation mBottomNavigation;
46
+    private BottomNavigation mBottomNavigation;
40
     private CoordinatorLayout mContentFrame;
47
     private CoordinatorLayout mContentFrame;
41
     private ArrayList<ScreenStack> mScreenStacks;
48
     private ArrayList<ScreenStack> mScreenStacks;
42
     private int mCurrentStackPosition = -1;
49
     private int mCurrentStackPosition = -1;
43
 
50
 
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
+
44
     @Override
78
     @Override
45
     protected void handleOnCreate() {
79
     protected void handleOnCreate() {
46
         super.handleOnCreate();
80
         super.handleOnCreate();
48
 
82
 
49
         setContentView(R.layout.bottom_tab_activity);
83
         setContentView(R.layout.bottom_tab_activity);
50
         mToolbar = (RnnToolBar) findViewById(R.id.toolbar);
84
         mToolbar = (RnnToolBar) findViewById(R.id.toolbar);
51
-        mBottomNavigation = (AHBottomNavigation) findViewById(R.id.bottom_tab_bar);
85
+        mBottomNavigation = (BottomNavigation) findViewById(R.id.bottom_tab_bar);
52
         mContentFrame = (CoordinatorLayout) findViewById(R.id.contentFrame);
86
         mContentFrame = (CoordinatorLayout) findViewById(R.id.contentFrame);
53
 
87
 
54
         final ArrayList<Screen> screens = (ArrayList<Screen>) getIntent().getSerializableExtra(EXTRA_SCREENS);
88
         final ArrayList<Screen> screens = (ArrayList<Screen>) getIntent().getSerializableExtra(EXTRA_SCREENS);
65
                 setupToolbar(screens);
99
                 setupToolbar(screens);
66
             }
100
             }
67
         });
101
         });
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
+        });
68
     }
114
     }
69
 
115
 
70
     private void setupPages(ArrayList<Screen> screens) {
116
     private void setupPages(ArrayList<Screen> screens) {
80
 
126
 
81
     private void setupBottomTabs(Screen initialScreen) {
127
     private void setupBottomTabs(Screen initialScreen) {
82
         if (initialScreen.bottomTabsHiddenOnScroll) {
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
+            }
83
 
160
 
161
+            if (child instanceof ViewGroup) {
162
+                return getScrollView((ViewGroup) child);
163
+            }
84
         }
164
         }
165
+
166
+        return null;
85
     }
167
     }
86
 
168
 
87
     @Override
169
     @Override
300
 
382
 
301
     private void setTabsWithIcons(ArrayList<Screen> screens, Map<Screen, Drawable> icons) {
383
     private void setTabsWithIcons(ArrayList<Screen> screens, Map<Screen, Drawable> icons) {
302
         mScreenStacks = new ArrayList<>();
384
         mScreenStacks = new ArrayList<>();
303
-        for (Screen screen : screens) {
385
+        for (int i = 0; i < screens.size(); i++) {
386
+            final Screen screen = screens.get(i);
304
             ScreenStack stack = new ScreenStack(this);
387
             ScreenStack stack = new ScreenStack(this);
305
-            stack.push(screen);
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
+
306
             mScreenStacks.add(stack);
400
             mScreenStacks.add(stack);
307
             AHBottomNavigationItem item = new AHBottomNavigationItem(screen.label, icons.get(screen), Color.GRAY);
401
             AHBottomNavigationItem item = new AHBottomNavigationItem(screen.label, icons.get(screen), Color.GRAY);
308
             mBottomNavigation.addItem(item);
402
             mBottomNavigation.addItem(item);

+ 3
- 2
android/app/src/main/java/com/reactnativenavigation/core/objects/Screen.java Datei anzeigen

5
 import android.support.annotation.ColorInt;
5
 import android.support.annotation.ColorInt;
6
 import android.support.annotation.NonNull;
6
 import android.support.annotation.NonNull;
7
 import android.support.annotation.Nullable;
7
 import android.support.annotation.Nullable;
8
+import android.util.Log;
8
 
9
 
9
 import com.facebook.react.bridge.ReadableArray;
10
 import com.facebook.react.bridge.ReadableArray;
10
 import com.facebook.react.bridge.ReadableMap;
11
 import com.facebook.react.bridge.ReadableMap;
56
     public final String icon;
57
     public final String icon;
57
     public ArrayList<Button> buttons;
58
     public ArrayList<Button> buttons;
58
     public final boolean backButtonHidden;
59
     public final boolean backButtonHidden;
59
-    public final boolean bottomTabsHiddenOnScroll;
60
+    public boolean bottomTabsHiddenOnScroll;
60
     public HashMap<String, Object> passedProps = new HashMap<>();
61
     public HashMap<String, Object> passedProps = new HashMap<>();
61
 
62
 
62
     // Navigation styling
63
     // Navigation styling
89
         }
90
         }
90
         buttons = getButtons(screen);
91
         buttons = getButtons(screen);
91
         backButtonHidden = getBoolean(screen, KEY_BACK_BUTTON_HIDDEN);
92
         backButtonHidden = getBoolean(screen, KEY_BACK_BUTTON_HIDDEN);
92
-        bottomTabsHiddenOnScroll = getBoolean(screen, KEY_BOTTOM_TABS_HIDDEN_ON_SCROLL);
93
         setToolbarStyle(screen);
93
         setToolbarStyle(screen);
94
     }
94
     }
95
 
95
 
138
             tabSelectedTextColor = getColor(style, KEY_TAB_SELECTED_TEXT_COLOR);
138
             tabSelectedTextColor = getColor(style, KEY_TAB_SELECTED_TEXT_COLOR);
139
             tabIndicatorColor = getColor(style, KEY_TAB_INDICATOR_COLOR);
139
             tabIndicatorColor = getColor(style, KEY_TAB_INDICATOR_COLOR);
140
             bottomTabsHidden = getBoolean(style, KEY_BOTTOM_TABS_HIDDEN);
140
             bottomTabsHidden = getBoolean(style, KEY_BOTTOM_TABS_HIDDEN);
141
+            bottomTabsHiddenOnScroll = getBoolean(style, KEY_BOTTOM_TABS_HIDDEN_ON_SCROLL);
141
         }
142
         }
142
     }
143
     }
143
 }
144
 }

+ 21
- 3
android/app/src/main/java/com/reactnativenavigation/utils/ReflectionUtils.java Datei anzeigen

9
 public class ReflectionUtils {
9
 public class ReflectionUtils {
10
 
10
 
11
     public static boolean setField(Object obj, String name, Object value) {
11
     public static boolean setField(Object obj, String name, Object value) {
12
-        Field field;
13
         try {
12
         try {
14
-            field = obj.getClass().getDeclaredField(name);
13
+            Field field = getField(obj.getClass(), name);
14
+            if (field == null) {
15
+                return false;
16
+            }
15
             field.setAccessible(true);
17
             field.setAccessible(true);
16
             field.set(obj, value);
18
             field.set(obj, value);
17
             return true;
19
             return true;
21
         return false;
23
         return false;
22
     }
24
     }
23
 
25
 
26
+    private static Field getField(Class clazz, String name) {
27
+        try {
28
+            return clazz.getDeclaredField(name);
29
+        } catch (NoSuchFieldException nsfe) {
30
+            return getField(clazz.getSuperclass(), name);
31
+        } catch (Exception e) {
32
+            return null;
33
+        }
34
+    }
35
+
36
+    /**
37
+     * Returns the value of the field
38
+     */
24
     public static Object getDeclaredField(Object obj, String fieldName) {
39
     public static Object getDeclaredField(Object obj, String fieldName) {
25
         try {
40
         try {
26
-            Field f = obj.getClass().getDeclaredField(fieldName);
41
+            Field f = getField(obj.getClass(), fieldName);
42
+            if (f == null) {
43
+                return null;
44
+            }
27
             f.setAccessible(true);
45
             f.setAccessible(true);
28
             return f.get(obj);
46
             return f.get(obj);
29
         } catch (Exception e) {
47
         } catch (Exception e) {

+ 1
- 12
android/app/src/main/java/com/reactnativenavigation/views/RctView.java Datei anzeigen

1
 package com.reactnativenavigation.views;
1
 package com.reactnativenavigation.views;
2
 
2
 
3
 import android.os.Bundle;
3
 import android.os.Bundle;
4
-import android.view.ViewTreeObserver;
5
 import android.widget.FrameLayout;
4
 import android.widget.FrameLayout;
6
 
5
 
7
 import com.facebook.react.ReactInstanceManager;
6
 import com.facebook.react.ReactInstanceManager;
34
         super(ctx);
33
         super(ctx);
35
         setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
34
         setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
36
 
35
 
37
-        mReactRootView = new ReactRootView(ctx);
36
+        mReactRootView = new RnnReactRootView(ctx, onDisplayedListener);
38
         mReactRootView.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
37
         mReactRootView.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
39
 
38
 
40
         String componentName = screen.screenId;
39
         String componentName = screen.screenId;
48
 
47
 
49
         mReactRootView.startReactApplication(rctInstanceManager, componentName, passProps);
48
         mReactRootView.startReactApplication(rctInstanceManager, componentName, passProps);
50
 
49
 
51
-        if (onDisplayedListener != null) {
52
-            mReactRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
53
-                @Override
54
-                public void onGlobalLayout() {
55
-                    onDisplayedListener.onDisplayed();
56
-                    mReactRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
57
-                }
58
-            });
59
-        }
60
-
61
         addView(mReactRootView);
50
         addView(mReactRootView);
62
     }
51
     }
63
 
52
 

+ 34
- 0
android/app/src/main/java/com/reactnativenavigation/views/RnnReactRootView.java Datei anzeigen

1
+package com.reactnativenavigation.views;
2
+
3
+import android.content.Context;
4
+import android.view.ViewTreeObserver;
5
+
6
+import com.facebook.react.ReactRootView;
7
+
8
+/**
9
+ * Created by guyc on 11/07/16.
10
+ */
11
+public class RnnReactRootView extends ReactRootView implements ViewTreeObserver.OnGlobalLayoutListener {
12
+    private final RctView.OnDisplayedListener mOnDisplayedListener;
13
+
14
+    public RnnReactRootView(Context context, RctView.OnDisplayedListener onDisplayedListener) {
15
+        super(context);
16
+        mOnDisplayedListener = onDisplayedListener;
17
+
18
+        if (onDisplayedListener != null) {
19
+            detectOnDisplay();
20
+        }
21
+    }
22
+
23
+    private void detectOnDisplay() {
24
+        getViewTreeObserver().addOnGlobalLayoutListener(this);
25
+    }
26
+
27
+    @Override
28
+    public void onGlobalLayout() {
29
+        if (getChildCount() >= 1) {
30
+            getViewTreeObserver().removeOnGlobalLayoutListener(this);
31
+            mOnDisplayedListener.onDisplayed();
32
+        }
33
+    }
34
+}