ソースを参照

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 年 前
コミット
6c11aad4ec

+ 22
- 34
android/app/src/main/java/com/reactnativenavigation/animation/VisibilityAnimator.java ファイルの表示

@@ -1,27 +1,23 @@
1 1
 package com.reactnativenavigation.animation;
2 2
 
3
-import android.animation.Animator;
4
-import android.animation.AnimatorListenerAdapter;
5 3
 import android.animation.ObjectAnimator;
6 4
 import android.support.v4.view.animation.LinearOutSlowInInterpolator;
7 5
 import android.view.View;
8 6
 
9 7
 public class VisibilityAnimator {
10 8
 
9
+    private final LinearOutSlowInInterpolator interpolator = new LinearOutSlowInInterpolator();
10
+    private ObjectAnimator animator;
11
+
11 12
     public enum HideDirection {
12 13
         Up, Down
13 14
     }
14 15
 
15
-    private enum VisibilityState {
16
-        Hidden, AnimateHide, Shown, AnimateShow
17
-    }
18
-
19 16
     private static final int SHOW_END_VALUE = 0;
20 17
     private static final int DURATION = 300;
21 18
 
22 19
     private final View view;
23 20
     private final int hiddenEndValue;
24
-    private VisibilityState visibilityState = VisibilityState.Shown;
25 21
 
26 22
     public VisibilityAnimator(View view, HideDirection hideDirection, int height) {
27 23
         this.view = view;
@@ -29,56 +25,48 @@ public class VisibilityAnimator {
29 25
     }
30 26
 
31 27
     public void setVisible(boolean visible, boolean animate) {
32
-        if (visible && isHiding()) {
28
+        cancelAnimator();
29
+        if (visible) {
33 30
             show(animate);
34
-        } else if (!visible && isShowing()) {
31
+        } else {
35 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 43
     private void show(boolean animate) {
40 44
         if (animate) {
41
-            ObjectAnimator animator = createAnimator(true);
45
+            animator = createAnimator(true);
42 46
             animator.start();
43 47
         } else {
44
-            visibilityState = VisibilityState.Shown;
48
+            view.setTranslationY(SHOW_END_VALUE);
49
+            view.setY(SHOW_END_VALUE);
45 50
             view.setVisibility(View.VISIBLE);
46 51
         }
47 52
     }
48 53
 
49 54
     private void hide(boolean animate) {
50 55
         if (animate) {
51
-            ObjectAnimator animator = createAnimator(false);
56
+            animator = createAnimator(false);
52 57
             animator.start();
53 58
         } else {
54
-            visibilityState = VisibilityState.Hidden;
59
+            view.setTranslationY(hiddenEndValue);
60
+            view.setY(hiddenEndValue);
55 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 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 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 70
         return animator;
83 71
     }
84 72
 }

+ 1
- 18
android/app/src/main/java/com/reactnativenavigation/screens/Screen.java ファイルの表示

@@ -11,7 +11,6 @@ import android.widget.RelativeLayout;
11 11
 
12 12
 import com.facebook.react.bridge.Callback;
13 13
 import com.reactnativenavigation.NavigationApplication;
14
-import com.reactnativenavigation.animation.VisibilityAnimator;
15 14
 import com.reactnativenavigation.controllers.NavigationActivity;
16 15
 import com.reactnativenavigation.events.ContextualMenuHiddenEvent;
17 16
 import com.reactnativenavigation.events.Event;
@@ -27,7 +26,6 @@ import com.reactnativenavigation.params.StyleParams;
27 26
 import com.reactnativenavigation.params.TitleBarButtonParams;
28 27
 import com.reactnativenavigation.params.TitleBarLeftButtonParams;
29 28
 import com.reactnativenavigation.params.parsers.StyleParamsParser;
30
-import com.reactnativenavigation.utils.ViewUtils;
31 29
 import com.reactnativenavigation.views.ContentView;
32 30
 import com.reactnativenavigation.views.LeftButtonOnClickListener;
33 31
 import com.reactnativenavigation.views.TopBar;
@@ -50,7 +48,6 @@ public abstract class Screen extends RelativeLayout implements Subscriber {
50 48
     protected final ScreenParams screenParams;
51 49
     protected TopBar topBar;
52 50
     private final LeftButtonOnClickListener leftButtonOnClickListener;
53
-    private VisibilityAnimator topBarVisibilityAnimator;
54 51
     private ScreenAnimator screenAnimator;
55 52
     protected StyleParams styleParams;
56 53
     public final SharedElements sharedElements;
@@ -149,23 +146,9 @@ public abstract class Screen extends RelativeLayout implements Subscriber {
149 146
     }
150 147
 
151 148
     private void addTopBar() {
152
-        createTopBarVisibilityAnimator();
153 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 152
     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
170 153
     private void setStatusBarColor(StyleParams.Color statusBarColor) {
171 154
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
@@ -209,7 +192,7 @@ public abstract class Screen extends RelativeLayout implements Subscriber {
209 192
 
210 193
     public void setTopBarVisible(boolean visible, boolean animate) {
211 194
         screenParams.styleParams.titleBarHidden = !visible;
212
-        topBarVisibilityAnimator.setVisible(visible, animate);
195
+        topBar.setVisible(visible, animate);
213 196
     }
214 197
 
215 198
     public void setTitleBarTitle(String title) {

+ 5
- 6
android/app/src/main/java/com/reactnativenavigation/views/TitleBar.java ファイルの表示

@@ -32,11 +32,6 @@ public class TitleBar extends Toolbar {
32 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 35
     @Override
41 36
     public void onViewAdded(View child) {
42 37
         super.onViewAdded(child);
@@ -76,7 +71,7 @@ public class TitleBar extends Toolbar {
76 71
     }
77 72
 
78 73
     public void setStyle(StyleParams params) {
79
-        setVisibility(params.titleBarHidden ? GONE : VISIBLE);
74
+        setVisibility(params.titleBarHidden);
80 75
         setTitleTextColor(params);
81 76
         setTitleTextFont(params);
82 77
         setSubtitleTextColor(params);
@@ -85,6 +80,10 @@ public class TitleBar extends Toolbar {
85 80
         centerTitle(params);
86 81
     }
87 82
 
83
+    public void setVisibility(boolean titleBarHidden) {
84
+        setVisibility(titleBarHidden ? GONE : VISIBLE);
85
+    }
86
+
88 87
     private void centerTitle(final StyleParams params) {
89 88
         final View titleView = getTitleView();
90 89
         if (titleView == null) {

+ 19
- 0
android/app/src/main/java/com/reactnativenavigation/views/TopBar.java ファイルの表示

@@ -8,6 +8,7 @@ import android.view.ViewGroup;
8 8
 import android.widget.FrameLayout;
9 9
 
10 10
 import com.facebook.react.bridge.Callback;
11
+import com.reactnativenavigation.animation.VisibilityAnimator;
11 12
 import com.reactnativenavigation.params.BaseScreenParams;
12 13
 import com.reactnativenavigation.params.ContextualMenuParams;
13 14
 import com.reactnativenavigation.params.StyleParams;
@@ -25,13 +26,26 @@ public class TopBar extends AppBarLayout {
25 26
     private ContextualMenu contextualMenu;
26 27
     protected FrameLayout titleBarAndContextualMenuContainer;
27 28
     protected TopTabs topTabs;
29
+    private VisibilityAnimator visibilityAnimator;
28 30
 
29 31
     public TopBar(Context context) {
30 32
         super(context);
31 33
         setId(ViewUtils.generateViewId());
34
+        createTopBarVisibilityAnimator();
32 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 49
     protected void createLayout() {
36 50
         titleBarAndContextualMenuContainer = new FrameLayout(getContext());
37 51
         addView(titleBarAndContextualMenuContainer);
@@ -163,4 +177,9 @@ public class TopBar extends AppBarLayout {
163 177
     public void onViewPagerScreenChanged(BaseScreenParams screenParams) {
164 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
 }