Explorar el Código

SetTopBarVisibility

Guy Carmeli hace 8 años
padre
commit
72c9faa0f3

android/app/src/main/java/com/reactnativenavigation/animation/OnScrollAnimator.java → android/app/src/main/java/com/reactnativenavigation/animation/VisibilityAnimator.java Ver fichero

@@ -8,24 +8,26 @@ import android.view.View;
8 8
 
9 9
 import com.reactnativenavigation.views.ScrollDirectionListener;
10 10
 
11
-public class OnScrollAnimator {
11
+// TODO find a better name for this class
12
+public class VisibilityAnimator {
12 13
 
13 14
     public enum HideDirection {
14 15
         Up, Down
15 16
     }
16 17
 
17
-    private enum State {
18
+    private enum VisibilityState {
18 19
         Hidden, AnimateHide, Shown, AnimateShow
19 20
     }
20 21
 
22
+    private static final int SHOW_END_VALUE = 0;
21 23
     private static final int DURATION = 300;
24
+
22 25
     private final View view;
23 26
     private final HideDirection hideDirection;
24 27
     private final int hiddenEndValue;
25
-    private final int shownEndValue = 0;
26
-    private State state = State.Shown;
28
+    private VisibilityState visibilityState = VisibilityState.Shown;
27 29
 
28
-    public OnScrollAnimator(View view, HideDirection hideDirection, int height) {
30
+    public VisibilityAnimator(View view, HideDirection hideDirection, int height) {
29 31
         this.view = view;
30 32
         this.hideDirection = hideDirection;
31 33
         this.hiddenEndValue = hideDirection == HideDirection.Up ? -height : height;
@@ -39,29 +41,47 @@ public class OnScrollAnimator {
39 41
         }
40 42
     }
41 43
 
42
-    public void show() {
43
-        ObjectAnimator animator = createAnimator(true);
44
-        animator.start();
45
-    }
46
-
47
-    public void hide() {
48
-        ObjectAnimator animator = createAnimator(false);
49
-        animator.start();
44
+    public void setVisible(boolean visible, boolean animate) {
45
+        if (isShowing() && !visible) {
46
+            hide(animate);
47
+        } else if (isHiding() && visible) {
48
+            show(animate);
49
+        }
50 50
     }
51 51
 
52 52
     private void handleUpHidingViews(ScrollDirectionListener.Direction scrollDirection) {
53
-        if (scrollUp(scrollDirection) && !showing()) {
54
-            show();
55
-        } else if (scrollDown(scrollDirection) && !hiding()) {
56
-            hide();
53
+        if (scrollUp(scrollDirection) && !isShowing()) {
54
+            show(true);
55
+        } else if (scrollDown(scrollDirection) && !isHiding()) {
56
+            hide(true);
57 57
         }
58 58
     }
59 59
 
60 60
     private void handleDownHidingViews(ScrollDirectionListener.Direction scrollDirection) {
61
-        if (scrollDown(scrollDirection) && !hiding()) {
62
-            hide();
63
-        } else if (scrollUp(scrollDirection) && !showing()) {
64
-            show();
61
+        if (scrollDown(scrollDirection) && !isHiding()) {
62
+            hide(true);
63
+        } else if (scrollUp(scrollDirection) && !isShowing()) {
64
+            show(true);
65
+        }
66
+    }
67
+
68
+    private void show(boolean animate) {
69
+        if (animate) {
70
+            ObjectAnimator animator = createAnimator(true);
71
+            animator.start();
72
+        } else {
73
+            visibilityState = VisibilityState.Shown;
74
+            view.setVisibility(View.VISIBLE);
75
+        }
76
+    }
77
+
78
+    private void hide(boolean animate) {
79
+        if (animate) {
80
+            ObjectAnimator animator = createAnimator(false);
81
+            animator.start();
82
+        } else {
83
+            visibilityState = VisibilityState.Hidden;
84
+            view.setVisibility(View.GONE);
65 85
         }
66 86
     }
67 87
 
@@ -73,30 +93,29 @@ public class OnScrollAnimator {
73 93
         return scrollDirection == ScrollDirectionListener.Direction.Down;
74 94
     }
75 95
 
76
-    private boolean showing() {
77
-        return state == State.Shown || state == State.AnimateShow;
96
+    private boolean isShowing() {
97
+        return visibilityState == VisibilityState.Shown || visibilityState == VisibilityState.AnimateShow;
78 98
     }
79 99
 
80
-    private boolean hiding() {
81
-        return state == State.Hidden || state == State.AnimateHide;
100
+    private boolean isHiding() {
101
+        return visibilityState == VisibilityState.Hidden || visibilityState == VisibilityState.AnimateHide;
82 102
     }
83 103
 
84 104
     private ObjectAnimator createAnimator(final boolean show) {
85
-        ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, show ? shownEndValue : hiddenEndValue);
105
+        ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, show ? SHOW_END_VALUE : hiddenEndValue);
86 106
         animator.setDuration(DURATION);
87 107
         animator.setInterpolator(new LinearOutSlowInInterpolator());
88 108
         animator.addListener(new AnimatorListenerAdapter() {
89 109
             @Override
90 110
             public void onAnimationStart(Animator animation) {
91
-                state = show ? State.AnimateShow : State.AnimateHide;
111
+                visibilityState = show ? VisibilityState.AnimateShow : VisibilityState.AnimateHide;
92 112
             }
93 113
 
94 114
             @Override
95 115
             public void onAnimationEnd(Animator animation) {
96
-                state = show ? State.Shown : State.Hidden;
116
+                visibilityState = show ? VisibilityState.Shown : VisibilityState.Hidden;
97 117
             }
98 118
         });
99 119
         return animator;
100 120
     }
101
-
102 121
 }

+ 2
- 1
android/app/src/main/java/com/reactnativenavigation/bridge/NavigationReactModule.java Ver fichero

@@ -58,7 +58,8 @@ public class NavigationReactModule extends ReactContextBaseJavaModule {
58 58
     }
59 59
 
60 60
     @ReactMethod
61
-    public void setTopBarVisible(final ReadableMap params) {
61
+    public void setTopBarVisible(String screenInstanceID, boolean hidden, boolean animated) {
62
+        NavigationCommandsHandler.toggleTopBarVisible(screenInstanceID, hidden, animated);
62 63
     }
63 64
 
64 65
     @ReactMethod

+ 4
- 0
android/app/src/main/java/com/reactnativenavigation/controllers/NavigationActivity.java Ver fichero

@@ -121,4 +121,8 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
121 121
     void newStack(ScreenParams params) {
122 122
         layout.newStack(params);
123 123
     }
124
+
125
+    void setTopBarVisible(String screenInstanceID, boolean hidden, boolean animated) {
126
+        layout.setTopBarVisible(screenInstanceID, hidden, animated);
127
+    }
124 128
 }

+ 14
- 0
android/app/src/main/java/com/reactnativenavigation/controllers/NavigationCommandsHandler.java Ver fichero

@@ -89,4 +89,18 @@ public class NavigationCommandsHandler {
89 89
             }
90 90
         });
91 91
     }
92
+
93
+    public static void toggleTopBarVisible(final String screenInstanceID, final boolean hidden, final boolean animated) {
94
+        final NavigationActivity currentActivity = NavigationActivity.currentActivity;
95
+        if (currentActivity == null) {
96
+            return;
97
+        }
98
+
99
+        NavigationApplication.instance.runOnMainThread(new Runnable() {
100
+            @Override
101
+            public void run() {
102
+                currentActivity.setTopBarVisible(screenInstanceID, hidden, animated);
103
+            }
104
+        });
105
+    }
92 106
 }

+ 2
- 0
android/app/src/main/java/com/reactnativenavigation/layouts/Layout.java Ver fichero

@@ -16,4 +16,6 @@ public interface Layout {
16 16
     void popToRoot(ScreenParams params);
17 17
 
18 18
     void newStack(ScreenParams params);
19
+
20
+    void setTopBarVisible(String screenInstanceID, boolean hidden, boolean animated);
19 21
 }

+ 24
- 6
android/app/src/main/java/com/reactnativenavigation/layouts/Screen.java Ver fichero

@@ -8,10 +8,11 @@ import android.os.Build;
8 8
 import android.view.Window;
9 9
 import android.widget.RelativeLayout;
10 10
 
11
-import com.reactnativenavigation.animation.OnScrollAnimator;
11
+import com.reactnativenavigation.animation.VisibilityAnimator;
12 12
 import com.reactnativenavigation.params.ScreenParams;
13 13
 import com.reactnativenavigation.params.ScreenStyleParams;
14 14
 import com.reactnativenavigation.utils.SdkSupports;
15
+import com.reactnativenavigation.utils.ViewUtils;
15 16
 import com.reactnativenavigation.views.ScrollDirectionListener;
16 17
 import com.reactnativenavigation.views.TopBar;
17 18
 
@@ -22,7 +23,7 @@ public abstract class Screen extends RelativeLayout implements ScrollDirectionLi
22 23
 
23 24
     protected final ScreenParams screenParams;
24 25
     protected TopBar topBar;
25
-    private OnScrollAnimator scrollAnimator;
26
+    private VisibilityAnimator topBarVisibilityAnimator;
26 27
 
27 28
     public Screen(Context context, ScreenParams screenParams) {
28 29
         super(context);
@@ -47,9 +48,21 @@ public abstract class Screen extends RelativeLayout implements ScrollDirectionLi
47 48
 
48 49
     private void createTopBar() {
49 50
         topBar = new TopBar(getContext());
51
+        createTopBarVisibilityAnimator();
50 52
         addView(topBar, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));
51 53
     }
52 54
 
55
+    private void createTopBarVisibilityAnimator() {
56
+        ViewUtils.runOnPreDraw(topBar, new Runnable() {
57
+            @Override
58
+            public void run() {
59
+                if (topBarVisibilityAnimator == null) {
60
+                    topBarVisibilityAnimator = new VisibilityAnimator(topBar, VisibilityAnimator.HideDirection.Up, topBar.getHeight());
61
+                }
62
+            }
63
+        });
64
+    }
65
+
53 66
     private void setStyle(ScreenStyleParams styleParams) {
54 67
         setStatusBarColor(styleParams.statusBarColor);
55 68
         setNavigationBarColor(styleParams.navigationBarColor);
@@ -88,13 +101,18 @@ public abstract class Screen extends RelativeLayout implements ScrollDirectionLi
88 101
 
89 102
     @Override
90 103
     public void onScrollChanged(ScrollDirectionListener.Direction direction) {
91
-        if (scrollAnimator == null) {
92
-            scrollAnimator = new OnScrollAnimator(topBar, OnScrollAnimator.HideDirection.Up, topBar.getHeight());
93
-        }
94
-        scrollAnimator.onScrollChanged(direction);
104
+        topBarVisibilityAnimator.onScrollChanged(direction);
95 105
     }
96 106
 
97 107
     public abstract void ensureUnmountOnDetachedFromWindow();
98 108
 
99 109
     public abstract void preventUnmountOnDetachedFromWindow();
110
+
111
+    public String getScreenInstanceId() {
112
+        return screenParams.screenInstanceId;
113
+    }
114
+
115
+    public void setTopBarVisible(boolean visible, boolean animate) {
116
+        topBarVisibilityAnimator.setVisible(visible, animate);
117
+    }
100 118
 }

+ 25
- 1
android/app/src/main/java/com/reactnativenavigation/layouts/ScreenStack.java Ver fichero

@@ -6,6 +6,7 @@ import android.widget.FrameLayout;
6 6
 
7 7
 import com.reactnativenavigation.params.ScreenParams;
8 8
 
9
+import java.util.Iterator;
9 10
 import java.util.Stack;
10 11
 
11 12
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
@@ -85,8 +86,31 @@ public class ScreenStack extends FrameLayout {
85 86
         return getStackSize() > 1;
86 87
     }
87 88
 
89
+    public void setTopBarVisible(String screenInstanceID, boolean visible, boolean animate) {
90
+        Screen screen = findScreenByScreenInstanceId(screenInstanceID);
91
+        if (screen != null) {
92
+            screen.setTopBarVisible(visible, animate);
93
+        }
94
+    }
88 95
 
89
-//    /**
96
+    private Screen findScreenByScreenInstanceId(String screenInstanceId) {
97
+        if (stack.isEmpty()) {
98
+            return null;
99
+        }
100
+
101
+        Iterator<Screen> iterator = stack.iterator();
102
+        while (iterator.hasNext()) {
103
+            Screen next = iterator.next();
104
+            if (next.getScreenInstanceId().equals(screenInstanceId)) {
105
+                return next;
106
+            }
107
+        }
108
+
109
+        return null;
110
+    }
111
+
112
+
113
+    //    /**
90 114
 //     * Remove the ScreenStack from {@code parent} while preventing all child react views from getting unmounted
91 115
 //        -= USE WHEN SWITCHING TABS =-
92 116
 //     */

+ 5
- 0
android/app/src/main/java/com/reactnativenavigation/layouts/SingleScreenLayout.java Ver fichero

@@ -66,4 +66,9 @@ public class SingleScreenLayout extends FrameLayout implements Layout {
66 66
     public void newStack(ScreenParams params) {
67 67
         createStack(getContext());
68 68
     }
69
+
70
+    @Override
71
+    public void setTopBarVisible(String screenInstanceID, boolean visible, boolean animate) {
72
+        stack.setTopBarVisible(screenInstanceID, visible, animate);
73
+    }
69 74
 }

+ 5
- 3
android/app/src/main/java/com/reactnativenavigation/params/ScreenParams.java Ver fichero

@@ -6,17 +6,19 @@ import java.util.List;
6 6
 
7 7
 public class ScreenParams {
8 8
     public String screenId;
9
-    public String screenInstanceId;
10 9
     public Bundle passProps;
11
-    public String navigatorEventId;
12 10
     public List<TitleBarButtonParams> buttons;
13 11
     public String title;
14 12
     public ScreenStyleParams styleParams;
15
-    public Bundle navigationParams;
16 13
     public List<TopTabParams> topTabParams;
17 14
     //    public String tabLabel; TODO when tabs are supported move to TabParams
18 15
     //    public Drawable tabIcon;
19 16
 
17
+    // TODO navigationParams should be a class with a `toBundle` method or something. Then we wouldn't neet to keep these two fields here
18
+    public String screenInstanceId;
19
+    public String navigatorEventId;
20
+    public Bundle navigationParams;
21
+
20 22
     public boolean hasTopTabs() {
21 23
         return topTabParams != null && !topTabParams.isEmpty();
22 24
     }

+ 1
- 0
android/app/src/main/java/com/reactnativenavigation/params/parsers/ScreenParamsParser.java Ver fichero

@@ -24,6 +24,7 @@ public class ScreenParamsParser extends Parser {
24 24
         assertKeyExists(params, KEY_NAVIGATION_PARAMS);
25 25
         result.navigationParams = params.getBundle(KEY_NAVIGATION_PARAMS);
26 26
         result.navigatorEventId = result.navigationParams.getString(KEY_NAVIGATOR_EVENT_ID);
27
+        result.screenInstanceId = result.navigationParams.getString(KEY_SCREEN_INSTANCE_ID);
27 28
         result.buttons = TitleBarButtonParamsParser.parse(params.getBundle(KEY_BUTTONS));
28 29
         result.title = params.getString(KEY_TITLE);
29 30
         result.styleParams = ScreenStyleParamsParser.parse(params.getBundle(STYLE_PARAMS));

+ 5
- 5
android/app/src/main/java/com/reactnativenavigation/views/TitleBar.java Ver fichero

@@ -4,7 +4,7 @@ import android.content.Context;
4 4
 import android.support.v7.widget.Toolbar;
5 5
 import android.view.Menu;
6 6
 
7
-import com.reactnativenavigation.animation.OnScrollAnimator;
7
+import com.reactnativenavigation.animation.VisibilityAnimator;
8 8
 import com.reactnativenavigation.params.TitleBarButtonParams;
9 9
 
10 10
 import java.util.List;
@@ -12,7 +12,7 @@ import java.util.List;
12 12
 public class TitleBar extends Toolbar {
13 13
 
14 14
     private boolean hideOnScroll = false;
15
-    private OnScrollAnimator onScrollAnimator;
15
+    private VisibilityAnimator visibilityAnimator;
16 16
 
17 17
     public TitleBar(Context context) {
18 18
         super(context);
@@ -36,14 +36,14 @@ public class TitleBar extends Toolbar {
36 36
 
37 37
     public void onScrollChanged(ScrollDirectionListener.Direction direction) {
38 38
         if (hideOnScroll) {
39
-            if (onScrollAnimator == null) {
39
+            if (visibilityAnimator == null) {
40 40
                 createScrollAnimator();
41 41
             }
42
-            onScrollAnimator.onScrollChanged(direction);
42
+            visibilityAnimator.onScrollChanged(direction);
43 43
         }
44 44
     }
45 45
 
46 46
     private void createScrollAnimator() {
47
-        onScrollAnimator = new OnScrollAnimator(this, OnScrollAnimator.HideDirection.Up, getHeight());
47
+        visibilityAnimator = new VisibilityAnimator(this, VisibilityAnimator.HideDirection.Up, getHeight());
48 48
     }
49 49
 }

+ 3
- 2
src/Screen.js Ver fichero

@@ -11,8 +11,9 @@ import _ from 'lodash';
11 11
 const _allNavigatorEventHandlers = {};
12 12
 
13 13
 class Navigator {
14
-  constructor(navigatorID, navigatorEventID) {
14
+  constructor(navigatorID, navigatorEventID, screenInstanceID) {
15 15
     this.navigatorID = navigatorID;
16
+    this.screenInstanceID = screenInstanceID;
16 17
     this.navigatorEventID = navigatorEventID;
17 18
     this.navigatorEventHandler = null;
18 19
     this.navigatorEventSubscription = null;
@@ -139,7 +140,7 @@ export default class Screen extends Component {
139 140
   constructor(props) {
140 141
     super(props);
141 142
     if (props.navigatorID) {
142
-      this.navigator = new Navigator(props.navigatorID, props.navigatorEventID);
143
+      this.navigator = new Navigator(props.navigatorID, props.navigatorEventID, props.screenInstanceID);
143 144
     }
144 145
   }
145 146
 

+ 9
- 4
src/deprecated/platformSpecificDeprecated.android.js Ver fichero

@@ -178,10 +178,15 @@ function navigatorToggleDrawer(navigator, params) {
178 178
 }
179 179
 
180 180
 function navigatorToggleNavBar(navigator, params) {
181
-  //RctActivity.toggleNavigationBar({
182
-  //  hidden: params.to === 'hidden',
183
-  //  animated: !(params.animated === false)
184
-  //});
181
+  const screenInstanceID = navigator.screenInstanceID;
182
+  const visible = params.to === 'shown';
183
+  const animated = !(params.animated === false);
184
+
185
+  newPlatformSpecific.toggleTopBarVisible(
186
+    screenInstanceID,
187
+    visible,
188
+    animated
189
+  );
185 190
 }
186 191
 
187 192
 function navigatorToggleTabs(navigator, params) {

+ 6
- 1
src/platformSpecific.android.js Ver fichero

@@ -32,10 +32,15 @@ function newStack(screenParams) {
32 32
   NativeModules.NavigationReactModule.newStack(screenParams);
33 33
 }
34 34
 
35
+function toggleTopBarVisible(screenInstanceID, visible, animated) {
36
+  NativeModules.NavigationReactModule.setTopBarVisible(screenInstanceID, visible, animated);
37
+}
38
+
35 39
 module.exports = {
36 40
   startApp,
37 41
   push,
38 42
   pop,
39 43
   popToRoot,
40
-  newStack
44
+  newStack,
45
+  toggleTopBarVisible
41 46
 };