Browse Source

Title bar visibility bug (#1346)

* Fix title bar not displayed if it was initially hidden

Also cleaned up VisibilityAnimator.

* Move visibility animator into topBar
Guy Carmeli 7 years ago
parent
commit
6c11aad4ec

+ 22
- 34
android/app/src/main/java/com/reactnativenavigation/animation/VisibilityAnimator.java View File

1
 package com.reactnativenavigation.animation;
1
 package com.reactnativenavigation.animation;
2
 
2
 
3
-import android.animation.Animator;
4
-import android.animation.AnimatorListenerAdapter;
5
 import android.animation.ObjectAnimator;
3
 import android.animation.ObjectAnimator;
6
 import android.support.v4.view.animation.LinearOutSlowInInterpolator;
4
 import android.support.v4.view.animation.LinearOutSlowInInterpolator;
7
 import android.view.View;
5
 import android.view.View;
8
 
6
 
9
 public class VisibilityAnimator {
7
 public class VisibilityAnimator {
10
 
8
 
9
+    private final LinearOutSlowInInterpolator interpolator = new LinearOutSlowInInterpolator();
10
+    private ObjectAnimator animator;
11
+
11
     public enum HideDirection {
12
     public enum HideDirection {
12
         Up, Down
13
         Up, Down
13
     }
14
     }
14
 
15
 
15
-    private enum VisibilityState {
16
-        Hidden, AnimateHide, Shown, AnimateShow
17
-    }
18
-
19
     private static final int SHOW_END_VALUE = 0;
16
     private static final int SHOW_END_VALUE = 0;
20
     private static final int DURATION = 300;
17
     private static final int DURATION = 300;
21
 
18
 
22
     private final View view;
19
     private final View view;
23
     private final int hiddenEndValue;
20
     private final int hiddenEndValue;
24
-    private VisibilityState visibilityState = VisibilityState.Shown;
25
 
21
 
26
     public VisibilityAnimator(View view, HideDirection hideDirection, int height) {
22
     public VisibilityAnimator(View view, HideDirection hideDirection, int height) {
27
         this.view = view;
23
         this.view = view;
29
     }
25
     }
30
 
26
 
31
     public void setVisible(boolean visible, boolean animate) {
27
     public void setVisible(boolean visible, boolean animate) {
32
-        if (visible && isHiding()) {
28
+        cancelAnimator();
29
+        if (visible) {
33
             show(animate);
30
             show(animate);
34
-        } else if (!visible && isShowing()) {
31
+        } else {
35
             hide(animate);
32
             hide(animate);
36
         }
33
         }
37
     }
34
     }
38
 
35
 
36
+    private void cancelAnimator() {
37
+        if (animator != null && animator.isRunning()) {
38
+            view.clearAnimation();
39
+            animator.cancel();
40
+        }
41
+    }
42
+
39
     private void show(boolean animate) {
43
     private void show(boolean animate) {
40
         if (animate) {
44
         if (animate) {
41
-            ObjectAnimator animator = createAnimator(true);
45
+            animator = createAnimator(true);
42
             animator.start();
46
             animator.start();
43
         } else {
47
         } else {
44
-            visibilityState = VisibilityState.Shown;
48
+            view.setTranslationY(SHOW_END_VALUE);
49
+            view.setY(SHOW_END_VALUE);
45
             view.setVisibility(View.VISIBLE);
50
             view.setVisibility(View.VISIBLE);
46
         }
51
         }
47
     }
52
     }
48
 
53
 
49
     private void hide(boolean animate) {
54
     private void hide(boolean animate) {
50
         if (animate) {
55
         if (animate) {
51
-            ObjectAnimator animator = createAnimator(false);
56
+            animator = createAnimator(false);
52
             animator.start();
57
             animator.start();
53
         } else {
58
         } else {
54
-            visibilityState = VisibilityState.Hidden;
59
+            view.setTranslationY(hiddenEndValue);
60
+            view.setY(hiddenEndValue);
55
             view.setVisibility(View.GONE);
61
             view.setVisibility(View.GONE);
56
         }
62
         }
57
     }
63
     }
58
 
64
 
59
-    private boolean isShowing() {
60
-        return visibilityState == VisibilityState.Shown || visibilityState == VisibilityState.AnimateShow;
61
-    }
62
-
63
-    private boolean isHiding() {
64
-        return visibilityState == VisibilityState.Hidden || visibilityState == VisibilityState.AnimateHide;
65
-    }
66
-
67
     private ObjectAnimator createAnimator(final boolean show) {
65
     private ObjectAnimator createAnimator(final boolean show) {
68
-        ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, show ? SHOW_END_VALUE : hiddenEndValue);
66
+        view.setVisibility(View.VISIBLE);
67
+        final ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, show ? SHOW_END_VALUE : hiddenEndValue);
69
         animator.setDuration(DURATION);
68
         animator.setDuration(DURATION);
70
-        animator.setInterpolator(new LinearOutSlowInInterpolator());
71
-        animator.addListener(new AnimatorListenerAdapter() {
72
-            @Override
73
-            public void onAnimationStart(Animator animation) {
74
-                visibilityState = show ? VisibilityState.AnimateShow : VisibilityState.AnimateHide;
75
-            }
76
-
77
-            @Override
78
-            public void onAnimationEnd(Animator animation) {
79
-                visibilityState = show ? VisibilityState.Shown : VisibilityState.Hidden;
80
-            }
81
-        });
69
+        animator.setInterpolator(interpolator);
82
         return animator;
70
         return animator;
83
     }
71
     }
84
 }
72
 }

+ 1
- 18
android/app/src/main/java/com/reactnativenavigation/screens/Screen.java View File

11
 
11
 
12
 import com.facebook.react.bridge.Callback;
12
 import com.facebook.react.bridge.Callback;
13
 import com.reactnativenavigation.NavigationApplication;
13
 import com.reactnativenavigation.NavigationApplication;
14
-import com.reactnativenavigation.animation.VisibilityAnimator;
15
 import com.reactnativenavigation.controllers.NavigationActivity;
14
 import com.reactnativenavigation.controllers.NavigationActivity;
16
 import com.reactnativenavigation.events.ContextualMenuHiddenEvent;
15
 import com.reactnativenavigation.events.ContextualMenuHiddenEvent;
17
 import com.reactnativenavigation.events.Event;
16
 import com.reactnativenavigation.events.Event;
27
 import com.reactnativenavigation.params.TitleBarButtonParams;
26
 import com.reactnativenavigation.params.TitleBarButtonParams;
28
 import com.reactnativenavigation.params.TitleBarLeftButtonParams;
27
 import com.reactnativenavigation.params.TitleBarLeftButtonParams;
29
 import com.reactnativenavigation.params.parsers.StyleParamsParser;
28
 import com.reactnativenavigation.params.parsers.StyleParamsParser;
30
-import com.reactnativenavigation.utils.ViewUtils;
31
 import com.reactnativenavigation.views.ContentView;
29
 import com.reactnativenavigation.views.ContentView;
32
 import com.reactnativenavigation.views.LeftButtonOnClickListener;
30
 import com.reactnativenavigation.views.LeftButtonOnClickListener;
33
 import com.reactnativenavigation.views.TopBar;
31
 import com.reactnativenavigation.views.TopBar;
50
     protected final ScreenParams screenParams;
48
     protected final ScreenParams screenParams;
51
     protected TopBar topBar;
49
     protected TopBar topBar;
52
     private final LeftButtonOnClickListener leftButtonOnClickListener;
50
     private final LeftButtonOnClickListener leftButtonOnClickListener;
53
-    private VisibilityAnimator topBarVisibilityAnimator;
54
     private ScreenAnimator screenAnimator;
51
     private ScreenAnimator screenAnimator;
55
     protected StyleParams styleParams;
52
     protected StyleParams styleParams;
56
     public final SharedElements sharedElements;
53
     public final SharedElements sharedElements;
149
     }
146
     }
150
 
147
 
151
     private void addTopBar() {
148
     private void addTopBar() {
152
-        createTopBarVisibilityAnimator();
153
         addView(topBar, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));
149
         addView(topBar, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));
154
     }
150
     }
155
 
151
 
156
-    private void createTopBarVisibilityAnimator() {
157
-        ViewUtils.runOnPreDraw(topBar, new Runnable() {
158
-            @Override
159
-            public void run() {
160
-                if (topBarVisibilityAnimator == null) {
161
-                    topBarVisibilityAnimator = new VisibilityAnimator(topBar,
162
-                            VisibilityAnimator.HideDirection.Up,
163
-                            topBar.getHeight());
164
-                }
165
-            }
166
-        });
167
-    }
168
-
169
     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
152
     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
170
     private void setStatusBarColor(StyleParams.Color statusBarColor) {
153
     private void setStatusBarColor(StyleParams.Color statusBarColor) {
171
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
154
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
209
 
192
 
210
     public void setTopBarVisible(boolean visible, boolean animate) {
193
     public void setTopBarVisible(boolean visible, boolean animate) {
211
         screenParams.styleParams.titleBarHidden = !visible;
194
         screenParams.styleParams.titleBarHidden = !visible;
212
-        topBarVisibilityAnimator.setVisible(visible, animate);
195
+        topBar.setVisible(visible, animate);
213
     }
196
     }
214
 
197
 
215
     public void setTitleBarTitle(String title) {
198
     public void setTitleBarTitle(String title) {

+ 5
- 6
android/app/src/main/java/com/reactnativenavigation/views/TitleBar.java View File

32
         super(context);
32
         super(context);
33
     }
33
     }
34
 
34
 
35
-    @Override
36
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
37
-        super.onLayout(changed, l, t, r, b);
38
-    }
39
-
40
     @Override
35
     @Override
41
     public void onViewAdded(View child) {
36
     public void onViewAdded(View child) {
42
         super.onViewAdded(child);
37
         super.onViewAdded(child);
76
     }
71
     }
77
 
72
 
78
     public void setStyle(StyleParams params) {
73
     public void setStyle(StyleParams params) {
79
-        setVisibility(params.titleBarHidden ? GONE : VISIBLE);
74
+        setVisibility(params.titleBarHidden);
80
         setTitleTextColor(params);
75
         setTitleTextColor(params);
81
         setTitleTextFont(params);
76
         setTitleTextFont(params);
82
         setSubtitleTextColor(params);
77
         setSubtitleTextColor(params);
85
         centerTitle(params);
80
         centerTitle(params);
86
     }
81
     }
87
 
82
 
83
+    public void setVisibility(boolean titleBarHidden) {
84
+        setVisibility(titleBarHidden ? GONE : VISIBLE);
85
+    }
86
+
88
     private void centerTitle(final StyleParams params) {
87
     private void centerTitle(final StyleParams params) {
89
         final View titleView = getTitleView();
88
         final View titleView = getTitleView();
90
         if (titleView == null) {
89
         if (titleView == null) {

+ 19
- 0
android/app/src/main/java/com/reactnativenavigation/views/TopBar.java View File

8
 import android.widget.FrameLayout;
8
 import android.widget.FrameLayout;
9
 
9
 
10
 import com.facebook.react.bridge.Callback;
10
 import com.facebook.react.bridge.Callback;
11
+import com.reactnativenavigation.animation.VisibilityAnimator;
11
 import com.reactnativenavigation.params.BaseScreenParams;
12
 import com.reactnativenavigation.params.BaseScreenParams;
12
 import com.reactnativenavigation.params.ContextualMenuParams;
13
 import com.reactnativenavigation.params.ContextualMenuParams;
13
 import com.reactnativenavigation.params.StyleParams;
14
 import com.reactnativenavigation.params.StyleParams;
25
     private ContextualMenu contextualMenu;
26
     private ContextualMenu contextualMenu;
26
     protected FrameLayout titleBarAndContextualMenuContainer;
27
     protected FrameLayout titleBarAndContextualMenuContainer;
27
     protected TopTabs topTabs;
28
     protected TopTabs topTabs;
29
+    private VisibilityAnimator visibilityAnimator;
28
 
30
 
29
     public TopBar(Context context) {
31
     public TopBar(Context context) {
30
         super(context);
32
         super(context);
31
         setId(ViewUtils.generateViewId());
33
         setId(ViewUtils.generateViewId());
34
+        createTopBarVisibilityAnimator();
32
         createLayout();
35
         createLayout();
33
     }
36
     }
34
 
37
 
38
+    private void createTopBarVisibilityAnimator() {
39
+        ViewUtils.runOnPreDraw(this, new Runnable() {
40
+            @Override
41
+            public void run() {
42
+                visibilityAnimator = new VisibilityAnimator(TopBar.this,
43
+                        VisibilityAnimator.HideDirection.Up,
44
+                        getHeight());
45
+            }
46
+        });
47
+    }
48
+
35
     protected void createLayout() {
49
     protected void createLayout() {
36
         titleBarAndContextualMenuContainer = new FrameLayout(getContext());
50
         titleBarAndContextualMenuContainer = new FrameLayout(getContext());
37
         addView(titleBarAndContextualMenuContainer);
51
         addView(titleBarAndContextualMenuContainer);
163
     public void onViewPagerScreenChanged(BaseScreenParams screenParams) {
177
     public void onViewPagerScreenChanged(BaseScreenParams screenParams) {
164
         titleBar.onViewPagerScreenChanged(screenParams);
178
         titleBar.onViewPagerScreenChanged(screenParams);
165
     }
179
     }
180
+
181
+    public void setVisible(boolean visible, boolean animate) {
182
+        titleBar.setVisibility(!visible);
183
+        visibilityAnimator.setVisible(visible, animate);
184
+    }
166
 }
185
 }