Browse Source

merged from mater

Daniel Zlotin 8 years ago
parent
commit
f973e957d3

+ 15
- 21
android/app/src/main/java/com/reactnativenavigation/activities/BottomTabActivity.java View File

@@ -5,7 +5,6 @@ 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.view.View;
9 8
 
10 9
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
11 10
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem;
@@ -14,6 +13,7 @@ import com.reactnativenavigation.R;
14 13
 import com.reactnativenavigation.core.objects.Drawer;
15 14
 import com.reactnativenavigation.core.objects.Screen;
16 15
 import com.reactnativenavigation.utils.StyleHelper;
16
+import com.reactnativenavigation.views.BottomNavigation;
17 17
 import com.reactnativenavigation.views.RnnToolBar;
18 18
 import com.reactnativenavigation.views.ScreenStack;
19 19
 
@@ -22,6 +22,7 @@ import java.util.HashMap;
22 22
 import java.util.Map;
23 23
 
24 24
 public class BottomTabActivity extends BaseReactActivity implements AHBottomNavigation.OnTabSelectedListener {
25
+    private static final String TAG = "BottomTabActivity";
25 26
     public static final String DRAWER_PARAMS = "drawerParams";
26 27
     public static final String EXTRA_SCREENS = "extraScreens";
27 28
 
@@ -35,7 +36,7 @@ public class BottomTabActivity extends BaseReactActivity implements AHBottomNavi
35 36
     private static int DEFAULT_TAB_SELECTED_COLOR = 0xFF0000FF;
36 37
     private static boolean DEFAULT_TAB_INACTIVE_TITLES = true;
37 38
 
38
-    private AHBottomNavigation mBottomNavigation;
39
+    private BottomNavigation mBottomNavigation;
39 40
     private CoordinatorLayout mContentFrame;
40 41
     private ArrayList<ScreenStack> mScreenStacks;
41 42
     private int mCurrentStackPosition = -1;
@@ -46,8 +47,8 @@ public class BottomTabActivity extends BaseReactActivity implements AHBottomNavi
46 47
         reactInstanceManager = RctManager.getInstance().getReactInstanceManager();
47 48
 
48 49
         setContentView(R.layout.bottom_tab_activity);
49
-        toolbar = (RnnToolBar) findViewById(R.id.toolbar);
50
-        mBottomNavigation = (AHBottomNavigation) findViewById(R.id.bottom_tab_bar);
50
+        mToolbar = (RnnToolBar) findViewById(R.id.toolbar);
51
+        mBottomNavigation = (BottomNavigation) findViewById(R.id.bottom_tab_bar);
51 52
         mContentFrame = (CoordinatorLayout) findViewById(R.id.contentFrame);
52 53
 
53 54
         final ArrayList<Screen> screens = (ArrayList<Screen>) getIntent().getSerializableExtra(EXTRA_SCREENS);
@@ -112,7 +113,7 @@ public class BottomTabActivity extends BaseReactActivity implements AHBottomNavi
112 113
         StyleHelper.updateStyles(toolbar, getCurrentScreen());
113 114
 
114 115
         if (shouldToggleTabs(screen)) {
115
-            toggleTabs(screen.bottomTabsHidden, false);
116
+            mBottomNavigation.toggleTabs(screen.bottomTabsHidden, false);
116 117
         }
117 118
     }
118 119
 
@@ -126,7 +127,7 @@ public class BottomTabActivity extends BaseReactActivity implements AHBottomNavi
126 127
                 StyleHelper.updateStyles(toolbar, currentScreen);
127 128
 
128 129
                 if (shouldToggleTabs(currentScreen)) {
129
-                    toggleTabs(currentScreen.bottomTabsHidden, false);
130
+                    mBottomNavigation.toggleTabs(currentScreen.bottomTabsHidden, false);
130 131
                 }
131 132
 
132 133
                 return popped;
@@ -145,7 +146,7 @@ public class BottomTabActivity extends BaseReactActivity implements AHBottomNavi
145 146
                 StyleHelper.updateStyles(toolbar, currentScreen);
146 147
 
147 148
                 if (shouldToggleTabs(currentScreen)) {
148
-                    toggleTabs(currentScreen.bottomTabsHidden, false);
149
+                    mBottomNavigation.toggleTabs(currentScreen.bottomTabsHidden, false);
149 150
                 }
150 151
 
151 152
                 return popped;
@@ -233,24 +234,17 @@ public class BottomTabActivity extends BaseReactActivity implements AHBottomNavi
233 234
     public void toggleTabs(ReadableMap params) {
234 235
         boolean hide = params.getBoolean(KEY_HIDDEN);
235 236
         boolean animated = params.getBoolean(KEY_ANIMATED);
236
-        toggleTabs(hide, animated);
237
-    }
238
-
239
-    // TODO: support animated = false -guyca
240
-    private void toggleTabs(boolean hide, boolean animated) {
241
-        if (hide) {
242
-//            mBottomNavigation.hideBottomNavigation(animated);
243
-            mBottomNavigation.setVisibility(View.GONE);
244
-        } else {
245
-            mBottomNavigation.setVisibility(View.VISIBLE);
246
-//            mBottomNavigation.restoreBottomNavigation(animated);
247
-        }
237
+        mBottomNavigation.toggleTabs(hide, animated);
248 238
     }
249 239
 
250 240
     private boolean shouldToggleTabs(Screen newScreen) {
251 241
         return mBottomNavigation.isShown() == newScreen.bottomTabsHidden;
252 242
     }
253 243
 
244
+    public void onScrollChanged(int direction) {
245
+        mBottomNavigation.onScroll(direction);
246
+    }
247
+
254 248
     private static class SetupTabsTask extends AsyncTask<Void, Void, Map<Screen, Drawable>> {
255 249
         private BottomTabActivity mActivity;
256 250
         private RnnToolBar mToolBar;
@@ -293,7 +287,8 @@ public class BottomTabActivity extends BaseReactActivity implements AHBottomNavi
293 287
 
294 288
     private void setTabsWithIcons(ArrayList<Screen> screens, Map<Screen, Drawable> icons) {
295 289
         mScreenStacks = new ArrayList<>();
296
-        for (Screen screen : screens) {
290
+        for (int i = 0; i < screens.size(); i++) {
291
+            final Screen screen = screens.get(i);
297 292
             ScreenStack stack = new ScreenStack(this);
298 293
             stack.push(screen);
299 294
             mScreenStacks.add(stack);
@@ -304,7 +299,6 @@ public class BottomTabActivity extends BaseReactActivity implements AHBottomNavi
304 299
         this.onTabSelected(0, false);
305 300
     }
306 301
 
307
-
308 302
     @Override
309 303
     protected void removeAllReactViews() {
310 304
         for (ScreenStack screenStack : mScreenStacks) {

+ 4
- 0
android/app/src/main/java/com/reactnativenavigation/core/objects/Screen.java View File

@@ -5,6 +5,7 @@ import android.graphics.drawable.Drawable;
5 5
 import android.support.annotation.ColorInt;
6 6
 import android.support.annotation.NonNull;
7 7
 import android.support.annotation.Nullable;
8
+import android.util.Log;
8 9
 
9 10
 import com.facebook.react.bridge.ReadableArray;
10 11
 import com.facebook.react.bridge.ReadableMap;
@@ -44,6 +45,7 @@ public class Screen extends JsonObject implements Serializable {
44 45
     private static final String KEY_TAB_SELECTED_TEXT_COLOR = "tabSelectedTextColor";
45 46
     private static final String KEY_TAB_INDICATOR_COLOR = "tabIndicatorColor";
46 47
     private static final String KEY_BOTTOM_TABS_HIDDEN = "tabBarHidden";
48
+    private static final String KEY_BOTTOM_TABS_HIDDEN_ON_SCROLL = "bottomTabsHiddenOnScroll";
47 49
     private static final String KEY_PROPS = "passProps";
48 50
 
49 51
     public String title;
@@ -55,6 +57,7 @@ public class Screen extends JsonObject implements Serializable {
55 57
     public final String icon;
56 58
     public ArrayList<Button> buttons;
57 59
     public final boolean backButtonHidden;
60
+    public boolean bottomTabsHiddenOnScroll;
58 61
     public HashMap<String, Object> passedProps = new HashMap<>();
59 62
 
60 63
     // NavigationReactModule styling
@@ -135,6 +138,7 @@ public class Screen extends JsonObject implements Serializable {
135 138
             tabSelectedTextColor = getColor(style, KEY_TAB_SELECTED_TEXT_COLOR);
136 139
             tabIndicatorColor = getColor(style, KEY_TAB_INDICATOR_COLOR);
137 140
             bottomTabsHidden = getBoolean(style, KEY_BOTTOM_TABS_HIDDEN);
141
+            bottomTabsHiddenOnScroll = getBoolean(style, KEY_BOTTOM_TABS_HIDDEN_ON_SCROLL);
138 142
         }
139 143
     }
140 144
 }

+ 21
- 3
android/app/src/main/java/com/reactnativenavigation/utils/ReflectionUtils.java View File

@@ -9,9 +9,11 @@ import java.lang.reflect.Method;
9 9
 public class ReflectionUtils {
10 10
 
11 11
     public static boolean setField(Object obj, String name, Object value) {
12
-        Field field;
13 12
         try {
14
-            field = obj.getClass().getDeclaredField(name);
13
+            Field field = getField(obj.getClass(), name);
14
+            if (field == null) {
15
+                return false;
16
+            }
15 17
             field.setAccessible(true);
16 18
             field.set(obj, value);
17 19
             return true;
@@ -21,9 +23,25 @@ public class ReflectionUtils {
21 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 39
     public static Object getDeclaredField(Object obj, String fieldName) {
25 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 45
             f.setAccessible(true);
28 46
             return f.get(obj);
29 47
         } catch (Exception e) {

+ 132
- 0
android/app/src/main/java/com/reactnativenavigation/views/BottomNavigation.java View File

@@ -0,0 +1,132 @@
1
+package com.reactnativenavigation.views;
2
+
3
+import android.animation.Animator;
4
+import android.animation.AnimatorListenerAdapter;
5
+import android.animation.ObjectAnimator;
6
+import android.content.Context;
7
+import android.support.v4.view.animation.LinearOutSlowInInterpolator;
8
+import android.util.AttributeSet;
9
+import android.util.Log;
10
+import android.view.View;
11
+
12
+import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
13
+
14
+/**
15
+ * Created by guyc on 10/07/16.
16
+ */
17
+public class BottomNavigation extends AHBottomNavigation {
18
+    private static final String TAG = "BottomNavigation";
19
+    public static final int SCROLL_DIRECTION_UP = 0;
20
+    public static final int SCROLL_DIRECTION_DOWN = 1;
21
+
22
+    private static final int STATE_HIDDEN = 0;
23
+    private static final int STATE_ANIMATE_HIDE = 1;
24
+    private static final int STATE_SHOWN = 2;
25
+    private static final int STATE_ANIMATE_SHOW = 3;
26
+    public static final int DURATION = 300;
27
+
28
+    private int mState = STATE_SHOWN;
29
+    private ObjectAnimator mHideAnimator;
30
+    private ObjectAnimator mShowAnimator;
31
+
32
+
33
+    public BottomNavigation(Context context) {
34
+        super(context);
35
+    }
36
+
37
+    public BottomNavigation(Context context, AttributeSet attrs) {
38
+        super(context, attrs);
39
+    }
40
+
41
+    public BottomNavigation(Context context, AttributeSet attrs, int defStyleAttr) {
42
+        super(context, attrs, defStyleAttr);
43
+    }
44
+
45
+    public void toggleTabs(boolean hide, boolean animated) {
46
+        if (hide) {
47
+            hide(animated);
48
+        } else {
49
+            show(animated);
50
+        }
51
+    }
52
+
53
+    private void hide(boolean animated) {
54
+        if (animated) {
55
+            hideAnimated();
56
+        } else {
57
+            setVisibility(View.GONE);
58
+        }
59
+    }
60
+
61
+    private void hideAnimated() {
62
+        if (mHideAnimator == null) {
63
+            mHideAnimator = createHideAnimator();
64
+        }
65
+
66
+        mHideAnimator.start();
67
+    }
68
+
69
+    private ObjectAnimator createHideAnimator() {
70
+        ObjectAnimator hideAnimator = ObjectAnimator.ofFloat(this, "translationY", getHeight());
71
+        hideAnimator.setDuration(DURATION);
72
+        hideAnimator.addListener(new AnimatorListenerAdapter() {
73
+            @Override
74
+            public void onAnimationStart(Animator animation) {
75
+                mState = STATE_ANIMATE_HIDE;
76
+            }
77
+
78
+            @Override
79
+            public void onAnimationEnd(Animator animation) {
80
+                mState = STATE_HIDDEN;
81
+            }
82
+        });
83
+        hideAnimator.setInterpolator(new LinearOutSlowInInterpolator());
84
+        return hideAnimator;
85
+
86
+    }
87
+
88
+    private void show(boolean animated) {
89
+        if (animated) {
90
+            showAnimated();
91
+        } else {
92
+            setVisibility(View.VISIBLE);
93
+        }
94
+    }
95
+
96
+    private void showAnimated() {
97
+        if (mShowAnimator == null) {
98
+            mShowAnimator = createShowAnimator();
99
+        }
100
+
101
+        mShowAnimator.start();
102
+    }
103
+
104
+    private ObjectAnimator createShowAnimator() {
105
+        ObjectAnimator showAnimator = ObjectAnimator.ofFloat(this, "translationY", 0);
106
+        showAnimator.setDuration(DURATION);
107
+        showAnimator.addListener(new AnimatorListenerAdapter() {
108
+            @Override
109
+            public void onAnimationStart(Animator animation) {
110
+                mState = STATE_ANIMATE_SHOW;
111
+            }
112
+
113
+            @Override
114
+            public void onAnimationEnd(Animator animation) {
115
+                mState = STATE_SHOWN;
116
+            }
117
+        });
118
+        showAnimator.setInterpolator(new LinearOutSlowInInterpolator());
119
+        return showAnimator;
120
+    }
121
+
122
+
123
+    public void onScroll(int direction) {
124
+        Log.d(TAG, "onScroll() called with: " + "direction = [" + direction + "]");
125
+        if (direction == SCROLL_DIRECTION_DOWN && mState == STATE_SHOWN) {
126
+            hide(true);
127
+
128
+        } else if (direction == SCROLL_DIRECTION_UP && mState == STATE_HIDDEN) {
129
+            show(true);
130
+        }
131
+    }
132
+}

+ 116
- 18
android/app/src/main/java/com/reactnativenavigation/views/RctView.java View File

@@ -1,12 +1,16 @@
1 1
 package com.reactnativenavigation.views;
2 2
 
3 3
 import android.os.Bundle;
4
+import android.view.View;
5
+import android.view.ViewGroup;
4 6
 import android.view.ViewTreeObserver;
5 7
 import android.widget.FrameLayout;
8
+import android.widget.ScrollView;
6 9
 
7 10
 import com.facebook.react.ReactInstanceManager;
8 11
 import com.facebook.react.ReactRootView;
9 12
 import com.reactnativenavigation.activities.BaseReactActivity;
13
+import com.reactnativenavigation.activities.BottomTabActivity;
10 14
 import com.reactnativenavigation.core.objects.Screen;
11 15
 import com.reactnativenavigation.utils.BridgeUtils;
12 16
 import com.reactnativenavigation.utils.ReflectionUtils;
@@ -16,7 +20,58 @@ import com.reactnativenavigation.utils.ReflectionUtils;
16 20
  */
17 21
 public class RctView extends FrameLayout {
18 22
 
19
-    private ReactRootView mReactRootView;
23
+    private BottomTabActivity context;
24
+    private ReactRootView reactRootView;
25
+    private ScrollView scrollView;
26
+    private int lastScrollY = -1;
27
+    private final ViewTreeObserver.OnScrollChangedListener scrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() {
28
+        @Override
29
+        public void onScrollChanged() {
30
+            if (!scrollView.getViewTreeObserver().isAlive()) {
31
+                return;
32
+            }
33
+
34
+            final int scrollY = scrollView.getScrollY();
35
+            if (scrollY != lastScrollY && // Scroll position changed
36
+                scrollY > 0 && // Ignore top overscroll
37
+                scrollY < (scrollView.getChildAt(0).getHeight() - scrollView.getHeight())) { // Ignore bottom overscroll
38
+                int direction = scrollY > lastScrollY ?
39
+                        BottomNavigation.SCROLL_DIRECTION_DOWN :
40
+                        BottomNavigation.SCROLL_DIRECTION_UP;
41
+                lastScrollY = scrollY;
42
+                context.onScrollChanged(direction);
43
+            }
44
+        }
45
+    };
46
+    private boolean isScrollEventListenerRegistered = false;
47
+
48
+    private final View.OnAttachStateChangeListener stateChangeListener =
49
+            new View.OnAttachStateChangeListener() {
50
+                @Override
51
+                public void onViewAttachedToWindow(View v) {
52
+                    scrollView = getScrollView((ViewGroup) getParent());
53
+
54
+                    if (scrollView != null && !isScrollEventListenerRegistered) {
55
+                        addScrollListener();
56
+                    }
57
+                }
58
+
59
+                @Override
60
+                public void onViewDetachedFromWindow(final View detachedView) {
61
+                    removeScrollListener();
62
+
63
+                    post(new Runnable() {
64
+                        @Override
65
+                        public void run() {
66
+                            scrollView = getScrollView((ViewGroup) getParent());
67
+                            if (scrollView != null && !isScrollEventListenerRegistered) {
68
+                                isScrollEventListenerRegistered = true;
69
+                                addScrollListener();
70
+                            }
71
+                        }
72
+                    });
73
+                }
74
+            };
20 75
 
21 76
     /**
22 77
      * Interface used to run some code when the {@link ReactRootView} is visible.
@@ -29,15 +84,33 @@ public class RctView extends FrameLayout {
29 84
     }
30 85
 
31 86
     @SuppressWarnings("unchecked")
32
-    public RctView(BaseReactActivity ctx, ReactInstanceManager rctInstanceManager, Screen screen,
87
+    public RctView(BaseReactActivity ctx, ReactInstanceManager rctInstanceManager, final Screen screen,
33 88
                    final OnDisplayedListener onDisplayedListener) {
34 89
         super(ctx);
35 90
         setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
36 91
 
37
-        mReactRootView = new ReactRootView(ctx);
38
-        mReactRootView.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
92
+        final OnDisplayedListener onDisplayedListenerInternal = screen.bottomTabsHiddenOnScroll ?
93
+            new OnDisplayedListener() {
94
+                @Override
95
+                public void onDisplayed() {
96
+                    if (onDisplayedListener != null) {
97
+                        onDisplayedListener.onDisplayed();
98
+                    }
99
+
100
+                    setupScrollViewWithBottomTabs();
101
+                }
102
+            } : onDisplayedListener;
39 103
 
104
+        reactRootView = new RnnReactRootView(ctx, onDisplayedListenerInternal);
105
+        reactRootView.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
106
+        Bundle passProps = createPassProps(screen);
40 107
         String componentName = screen.screenId;
108
+        reactRootView.startReactApplication(rctInstanceManager, componentName, passProps);
109
+
110
+        addView(reactRootView);
111
+    }
112
+
113
+    private Bundle createPassProps(Screen screen) {
41 114
         Bundle passProps = new Bundle();
42 115
         passProps.putString(Screen.KEY_SCREEN_INSTANCE_ID, screen.screenInstanceId);
43 116
         passProps.putString(Screen.KEY_NAVIGATOR_ID, screen.navigatorId);
@@ -45,20 +118,44 @@ public class RctView extends FrameLayout {
45 118
         if (screen.passedProps != null) {
46 119
             BridgeUtils.addMapToBundle(screen.passedProps, passProps);
47 120
         }
121
+        return passProps;
122
+    }
48 123
 
49
-        mReactRootView.startReactApplication(rctInstanceManager, componentName, passProps);
124
+    private void setupScrollViewWithBottomTabs() {
125
+        scrollView = getScrollView((ViewGroup) getParent());
126
+        if (scrollView != null) {
127
+            context = (BottomTabActivity) getContext();
128
+            attachStateChangeListener(scrollView);
129
+            addScrollListener();
130
+        }
131
+    }
50 132
 
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
-            });
133
+    private ScrollView getScrollView(ViewGroup parent) {
134
+        for (int i = 0; i < parent.getChildCount(); i++) {
135
+            View child = parent.getChildAt(i);
136
+
137
+            if (child instanceof ScrollView) {
138
+                return (ScrollView) child;
139
+            }
140
+
141
+            if (child instanceof ViewGroup) {
142
+                return getScrollView((ViewGroup) child);
143
+            }
59 144
         }
60 145
 
61
-        addView(mReactRootView);
146
+        return null;
147
+    }
148
+
149
+    private void attachStateChangeListener(ScrollView scrollView) {
150
+        scrollView.addOnAttachStateChangeListener(stateChangeListener);
151
+    }
152
+
153
+    private void addScrollListener() {
154
+        scrollView.getViewTreeObserver().addOnScrollChangedListener(scrollChangedListener);
155
+    }
156
+
157
+    private void removeScrollListener() {
158
+        scrollView.getViewTreeObserver().removeOnScrollChangedListener(scrollChangedListener);
62 159
     }
63 160
 
64 161
     /**
@@ -67,7 +164,8 @@ public class RctView extends FrameLayout {
67 164
      */
68 165
     public void onTemporallyRemovedFromScreen() {
69 166
         // Hack in order to prevent the react view from getting unmounted
70
-        ReflectionUtils.setField(mReactRootView, "mAttachScheduled", true);
167
+
168
+        ReflectionUtils.setField(reactRootView, "mAttachScheduled", true);
71 169
     }
72 170
 
73 171
     /**
@@ -75,7 +173,7 @@ public class RctView extends FrameLayout {
75 173
      * executed and componentWillUnmount is called
76 174
      */
77 175
     public void onRemoveFromScreen() {
78
-        ReflectionUtils.setField(mReactRootView, "mAttachScheduled", false);
176
+        ReflectionUtils.setField(reactRootView, "mAttachScheduled", false);
79 177
     }
80 178
 
81 179
     /**
@@ -83,11 +181,11 @@ public class RctView extends FrameLayout {
83 181
      * executed and componentWillUnmount is called
84 182
      */
85 183
     public void onReAddToScreen() {
86
-        ReflectionUtils.setField(mReactRootView, "mAttachScheduled", false);
184
+        ReflectionUtils.setField(reactRootView, "mAttachScheduled", false);
87 185
     }
88 186
 
89 187
     public void detachFromScreen() {
90
-        ReflectionUtils.invoke(mReactRootView, "onDetachedFromWindow");
188
+        ReflectionUtils.invoke(reactRootView, "onDetachedFromWindow");
91 189
     }
92 190
 }
93 191
 

+ 34
- 0
android/app/src/main/java/com/reactnativenavigation/views/RnnReactRootView.java View File

@@ -0,0 +1,34 @@
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
+}

+ 2
- 2
android/gradle/wrapper/gradle-wrapper.properties View File

@@ -1,6 +1,6 @@
1
-#Mon Dec 28 10:00:20 PST 2015
1
+#Wed Jul 13 11:11:29 IDT 2016
2 2
 distributionBase=GRADLE_USER_HOME
3 3
 distributionPath=wrapper/dists
4 4
 zipStoreBase=GRADLE_USER_HOME
5 5
 zipStorePath=wrapper/dists
6
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
6
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip