Guy Carmeli 8 年前
父节点
当前提交
6933a61b3b

+ 4
- 4
android/app/src/main/java/com/reactnativenavigation/screens/CollapsingSingleScreen.java 查看文件

@@ -35,13 +35,13 @@ public class CollapsingSingleScreen extends SingleScreen {
35 35
     @Override
36 36
     protected void createContent() {
37 37
         contentView = new ContentView(getContext(), screenParams.screenId, screenParams.navigationParams);
38
-        contentView.setViewMeasurer(new CollapsingContentViewMeasurer((CollapsingTopBar) topBar));
39
-        setupScrollDetection((CollapsingTopBar) topBar);
38
+        contentView.setViewMeasurer(new CollapsingContentViewMeasurer((CollapsingTopBar) topBar, this));
39
+        setupCollapseDetection((CollapsingTopBar) topBar);
40 40
         addView(contentView, createLayoutParams());
41 41
     }
42 42
 
43
-    private void setupScrollDetection(final CollapsingTopBar topBar) {
44
-        contentView.setupScrollDetection(new ScrollListener(topBar,
43
+    private void setupCollapseDetection(final CollapsingTopBar topBar) {
44
+        contentView.setupCollapseDetection(new ScrollListener(topBar,
45 45
                 new ScrollListener.OnScrollListener() {
46 46
                     @Override
47 47
                     public void onScroll(float amount) {

+ 4
- 4
android/app/src/main/java/com/reactnativenavigation/views/ContentView.java 查看文件

@@ -42,7 +42,7 @@ public class ContentView extends ReactRootView {
42 42
         viewMeasurer = new ViewMeasurer();
43 43
     }
44 44
 
45
-    public void setupScrollDetection(ScrollListener scrollListener) {
45
+    public void setupCollapseDetection(ScrollListener scrollListener) {
46 46
         scrollViewDelegate = new ScrollViewDelegate(scrollListener);
47 47
     }
48 48
 
@@ -90,10 +90,10 @@ public class ContentView extends ReactRootView {
90 90
         }
91 91
     }
92 92
 
93
-    private void onScrollViewAdded(ScrollView child) {
93
+    private void onScrollViewAdded(ScrollView scrollView) {
94 94
         if (scrollViewDelegate != null) {
95
-            scrollViewDelegate.onScrollViewAdded(child);
96
-            scrollViewAddedListener.onScrollViewAdded(child);
95
+            scrollViewDelegate.onScrollViewAdded(scrollView);
96
+            scrollViewAddedListener.onScrollViewAdded(scrollView);
97 97
         }
98 98
     }
99 99
 

+ 1
- 1
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapseAmount.java 查看文件

@@ -1,7 +1,7 @@
1 1
 package com.reactnativenavigation.views.collapsingToolbar;
2 2
 
3 3
 public class CollapseAmount {
4
-    public static CollapseAmount NONE = new CollapseAmount();
4
+    public final static CollapseAmount None = new CollapseAmount();
5 5
     private Float amount;
6 6
 
7 7
     public CollapseAmount(float amount) {

+ 13
- 23
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapseCalculator.java 查看文件

@@ -5,8 +5,6 @@ import android.support.annotation.Nullable;
5 5
 import android.view.MotionEvent;
6 6
 import android.widget.ScrollView;
7 7
 
8
-import com.reactnativenavigation.utils.ViewUtils;
9
-
10 8
 class CollapseCalculator {
11 9
     private float collapse;
12 10
     private MotionEvent previousTouchEvent;
@@ -18,16 +16,9 @@ class CollapseCalculator {
18 16
     private boolean canExpend = false;
19 17
     private CollapsingView view;
20 18
     protected ScrollView scrollView;
21
-    private static float finalCollapsedTranslation;
22 19
 
23 20
     CollapseCalculator(final CollapsingView collapsingView) {
24 21
         this.view = collapsingView;
25
-        ViewUtils.runOnPreDraw(view.asView(), new Runnable() {
26
-            @Override
27
-            public void run() {
28
-                finalCollapsedTranslation = view.getFinalCollapseValue();
29
-            }
30
-        });
31 22
     }
32 23
 
33 24
     void setScrollView(ScrollView scrollView) {
@@ -38,25 +29,24 @@ class CollapseCalculator {
38 29
     CollapseAmount calculate(MotionEvent event) {
39 30
         updateInitialTouchY(event);
40 31
         if (!isMoveEvent(event)) {
41
-            return CollapseAmount.NONE;
32
+            return CollapseAmount.None;
42 33
         }
43 34
 
44
-        if (shouldTranslateTopBarAndScrollView(event)) {
35
+        if (shouldCollapse(event)) {
45 36
             return calculateCollapse(event);
46 37
         } else {
47 38
             previousCollapseY = -1;
48 39
             previousTouchEvent = MotionEvent.obtain(event);
49
-            return CollapseAmount.NONE;
40
+            return CollapseAmount.None;
50 41
         }
51 42
     }
52 43
 
53
-    private boolean shouldTranslateTopBarAndScrollView(MotionEvent event) {
44
+    private boolean shouldCollapse(MotionEvent event) {
54 45
         checkCollapseLimits();
55 46
         ScrollDirection.Direction direction = getScrollDirection(event.getRawY());
56
-        return isMoveEvent(event) &&
57
-               (isNotCollapsedOrExpended() ||
47
+        return isNotCollapsedOrExpended() ||
58 48
                 (canCollapse && isExpendedAndScrollingUp(direction)) ||
59
-                (canExpend && isCollapsedAndScrollingDown(direction)));
49
+                (canExpend && isCollapsedAndScrollingDown(direction));
60 50
     }
61 51
 
62 52
     private ScrollDirection.Direction getScrollDirection(float y) {
@@ -72,12 +62,12 @@ class CollapseCalculator {
72 62
     }
73 63
 
74 64
     private void checkCollapseLimits() {
75
-        float currentTopBarTranslation = view.getCurrentCollapseValue();
65
+        float currentCollapse = view.getCurrentCollapseValue();
76 66
         float finalExpendedTranslation = 0;
77
-        isExpended = isExpended(currentTopBarTranslation, finalExpendedTranslation);
78
-        isCollapsed = isCollapsed(currentTopBarTranslation, finalCollapsedTranslation);
79
-        canCollapse = calculateCanCollapse(currentTopBarTranslation, finalExpendedTranslation, finalCollapsedTranslation);
80
-        canExpend = calculateCanExpend(currentTopBarTranslation, finalExpendedTranslation, finalCollapsedTranslation);
67
+        isExpended = isExpended(currentCollapse, finalExpendedTranslation);
68
+        isCollapsed = isCollapsed(currentCollapse, view.getFinalCollapseValue());
69
+        canCollapse = calculateCanCollapse(currentCollapse, finalExpendedTranslation, view.getFinalCollapseValue());
70
+        canExpend = calculateCanExpend(currentCollapse, finalExpendedTranslation, view.getFinalCollapseValue());
81 71
     }
82 72
 
83 73
     private boolean calculateCanCollapse(float currentTopBarTranslation, float finalExpendedTranslation, float finalCollapsedTranslation) {
@@ -124,8 +114,8 @@ class CollapseCalculator {
124 114
 
125 115
     private float calculateCollapse(float y) {
126 116
         float translation = y - previousCollapseY + view.getCurrentCollapseValue();
127
-        if (translation < finalCollapsedTranslation) {
128
-            translation = finalCollapsedTranslation;
117
+        if (translation < view.getFinalCollapseValue()) {
118
+            translation = view.getFinalCollapseValue();
129 119
         }
130 120
         final float expendedTranslation = 0;
131 121
         if (translation > expendedTranslation) {

+ 20
- 4
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapsingContentViewMeasurer.java 查看文件

@@ -1,15 +1,31 @@
1 1
 package com.reactnativenavigation.views.collapsingToolbar;
2 2
 
3
+import com.reactnativenavigation.screens.Screen;
4
+import com.reactnativenavigation.utils.ViewUtils;
3 5
 import com.reactnativenavigation.views.utils.ViewMeasurer;
4 6
 
5 7
 public class CollapsingContentViewMeasurer extends ViewMeasurer {
6
-    private final float titleBarHeight;
7
-    public CollapsingContentViewMeasurer(CollapsingTopBar topBar) {
8
-        titleBarHeight = topBar.getTitleBarHeight();
8
+    private int titleBarHeight;
9
+    private int screenHeight;
10
+
11
+    public CollapsingContentViewMeasurer(final CollapsingTopBar topBar, final Screen collapsingSingleScreen) {
12
+        ViewUtils.runOnPreDraw(topBar, new Runnable() {
13
+            @Override
14
+            public void run() {
15
+                titleBarHeight = topBar.getCollapsedHeight();
16
+            }
17
+        });
18
+
19
+        ViewUtils.runOnPreDraw(collapsingSingleScreen, new Runnable() {
20
+            @Override
21
+            public void run() {
22
+                screenHeight = collapsingSingleScreen.getMeasuredHeight();
23
+            }
24
+        });
9 25
     }
10 26
 
11 27
     @Override
12 28
     public int getMeasuredHeight(int heightMeasureSpec) {
13
-        return (int) (super.getMeasuredHeight(heightMeasureSpec) + CollapsingToolBar.MAX_HEIGHT - titleBarHeight);
29
+        return screenHeight - titleBarHeight;
14 30
     }
15 31
 }

+ 14
- 15
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapsingTextView.java 查看文件

@@ -8,6 +8,7 @@ import android.graphics.Paint;
8 8
 import android.support.annotation.FloatRange;
9 9
 import android.support.v4.widget.TextViewCompat;
10 10
 import android.support.v7.widget.TintTypedArray;
11
+import android.text.TextPaint;
11 12
 import android.view.animation.DecelerateInterpolator;
12 13
 import android.view.animation.Interpolator;
13 14
 import android.widget.FrameLayout;
@@ -25,11 +26,10 @@ public class CollapsingTextView extends FrameLayout {
25 26
     private TextView dummy;
26 27
     private String text;
27 28
     private Paint paint;
28
-    private float initialY;
29
+    private float initialY = -1;
29 30
     private float currentY;
30 31
     private float collapseY;
31 32
     private float collapseFraction;
32
-    private int[] positionOnScreen;
33 33
     private Interpolator scaleInterpolator;
34 34
     private float expendedTextSize;
35 35
     private float collapsedTextSize;
@@ -62,21 +62,9 @@ public class CollapsingTextView extends FrameLayout {
62 62
     }
63 63
 
64 64
     private void createTextPaint() {
65
-        paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG);
65
+        paint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG);
66 66
         paint.setColor(Color.GREEN);
67 67
         paint.setTextSize(expendedTextSize);
68
-
69
-        ViewUtils.runOnPreDraw(dummy, new Runnable() {
70
-            @Override
71
-            public void run() {
72
-                positionOnScreen = new int[2];
73
-                getLocationInWindow(positionOnScreen);
74
-                currentY = initialY = positionOnScreen[1] + getMeasuredHeight() - dummy.getMeasuredHeight();
75
-                float bottomMargin = ViewUtils.convertDpToPixel(10);
76
-                collapseY = positionOnScreen[1] + bottomMargin;
77
-                invalidate();
78
-            }
79
-        });
80 68
     }
81 69
 
82 70
     public void setText(String text) {
@@ -108,10 +96,21 @@ public class CollapsingTextView extends FrameLayout {
108 96
     @Override
109 97
     protected void onDraw(Canvas canvas) {
110 98
         super.onDraw(canvas);
99
+        if (initialY == -1) {
100
+            calculateTextPosition();
101
+        }
111 102
         paint.setTextSize(linearInterpolation(expendedTextSize, collapsedTextSize, collapseFraction));
112 103
         canvas.drawText(text, 0, currentY, paint);
113 104
     }
114 105
 
106
+    private void calculateTextPosition() {
107
+        final int[] positionOnScreen = new int[2];
108
+        getLocationInWindow(positionOnScreen);
109
+        currentY = initialY = positionOnScreen[1] + getMeasuredHeight() - dummy.getMeasuredHeight();
110
+        float bottomMargin = ViewUtils.convertDpToPixel(10);
111
+        collapseY = positionOnScreen[1] + bottomMargin;
112
+    }
113
+
115 114
     private float linearInterpolation(float from, float to, float fraction) {
116 115
         fraction = scaleInterpolator.getInterpolation(fraction);
117 116
         return from + (fraction * (to - from));

+ 22
- 13
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapsingTopBar.java 查看文件

@@ -5,16 +5,25 @@ import android.view.View;
5 5
 import android.widget.ScrollView;
6 6
 
7 7
 import com.reactnativenavigation.params.CollapsingTopBarParams;
8
+import com.reactnativenavigation.utils.ViewUtils;
8 9
 import com.reactnativenavigation.views.TitleBar;
9 10
 import com.reactnativenavigation.views.TopBar;
10 11
 
11 12
 public class CollapsingTopBar extends TopBar implements CollapsingView {
12
-    private CollapsingToolBar collapsingToolBar;
13
+    private CollapsingTopBarBackground collapsingTopBarBackground;
13 14
     private ScrollListener scrollListener;
15
+    private float finalCollapsedTranslation;
14 16
 
15 17
     public CollapsingTopBar(Context context, CollapsingTopBarParams params) {
16 18
         super(context);
17 19
         createCollapsingTopBar(params);
20
+        ViewUtils.runOnPreDraw(this, new Runnable() {
21
+            @Override
22
+            public void run() {
23
+                finalCollapsedTranslation = getCollapsingTopBarBackground().getCollapsedTopBarHeight() - getHeight();
24
+            }
25
+        });
26
+
18 27
     }
19 28
 
20 29
     public void setScrollListener(ScrollListener scrollListener) {
@@ -22,30 +31,26 @@ public class CollapsingTopBar extends TopBar implements CollapsingView {
22 31
     }
23 32
 
24 33
     private void createCollapsingTopBar(CollapsingTopBarParams params) {
25
-        collapsingToolBar = new CollapsingToolBar(getContext(), params);
26
-        LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, (int) CollapsingToolBar.MAX_HEIGHT);
27
-        titleBarAndContextualMenuContainer.addView(collapsingToolBar, lp);
34
+        collapsingTopBarBackground = new CollapsingTopBarBackground(getContext(), params);
35
+        LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, (int) CollapsingTopBarBackground.MAX_HEIGHT);
36
+        titleBarAndContextualMenuContainer.addView(collapsingTopBarBackground, lp);
28 37
     }
29 38
 
30 39
     @Override
31 40
     protected TitleBar createTitleBar() {
32 41
         return new CollapsingTitleBar(getContext(),
33
-                collapsingToolBar.getCollapsedTopBarHeight(),
42
+                collapsingTopBarBackground.getCollapsedTopBarHeight(),
34 43
                 scrollListener);
35 44
     }
36 45
 
37
-    public int getTitleBarHeight() {
38
-        return titleBar.getMeasuredHeight();
39
-    }
40
-
41
-    public CollapsingToolBar getCollapsingToolBar() {
42
-        return collapsingToolBar;
46
+    public CollapsingTopBarBackground getCollapsingTopBarBackground() {
47
+        return collapsingTopBarBackground;
43 48
     }
44 49
 
45 50
     public void collapse(float collapse) {
46 51
         setTranslationY(collapse);
47 52
         ((CollapsingTitleBar) titleBar).collapse(collapse);
48
-        collapsingToolBar.collapse(collapse);
53
+        collapsingTopBarBackground.collapse(collapse);
49 54
     }
50 55
 
51 56
     public void onScrollViewAdded(ScrollView scrollView) {
@@ -54,7 +59,11 @@ public class CollapsingTopBar extends TopBar implements CollapsingView {
54 59
 
55 60
     @Override
56 61
     public float getFinalCollapseValue() {
57
-        return getCollapsingToolBar().getCollapsedTopBarHeight() - getHeight();
62
+        return finalCollapsedTranslation;
63
+    }
64
+
65
+    public int getCollapsedHeight() {
66
+        return collapsingTopBarBackground.getCollapsedTopBarHeight();
58 67
     }
59 68
 
60 69
     @Override

android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapsingToolBar.java → android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapsingTopBarBackground.java 查看文件

@@ -6,21 +6,20 @@ import android.widget.FrameLayout;
6 6
 import android.widget.ImageView;
7 7
 
8 8
 import com.facebook.drawee.view.SimpleDraweeView;
9
-import com.reactnativenavigation.R;
10 9
 import com.reactnativenavigation.params.CollapsingTopBarParams;
11 10
 import com.reactnativenavigation.utils.ViewUtils;
12 11
 import com.reactnativenavigation.views.Scrim;
13 12
 
14 13
 import static android.widget.FrameLayout.LayoutParams.MATCH_PARENT;
15 14
 
16
-public class CollapsingToolBar extends FrameLayout {
15
+public class CollapsingTopBarBackground extends FrameLayout {
17 16
     public static final float MAX_HEIGHT = ViewUtils.convertDpToPixel(256);
18 17
     private final CollapsingTopBarParams params;
19 18
     private SimpleDraweeView backdrop;
20 19
     private Scrim scrim;
21 20
     private int topBarHeight = -1;
22 21
 
23
-    public CollapsingToolBar(Context context, CollapsingTopBarParams params) {
22
+    public CollapsingTopBarBackground(Context context, CollapsingTopBarParams params) {
24 23
         super(context);
25 24
         this.params = params;
26 25
         setFitsSystemWindows(true);
@@ -56,7 +55,7 @@ public class CollapsingToolBar extends FrameLayout {
56 55
         return topBarHeight;
57 56
     }
58 57
     private void calculateTopBarHeight() {
59
-        int[] attrs = new int[] {R.attr.actionBarSize};
58
+        int[] attrs = new int[] {android.R.attr.actionBarSize};
60 59
         TypedArray ta = getContext().obtainStyledAttributes(attrs);
61 60
         topBarHeight = ta.getDimensionPixelSize(0, -1);
62 61
         ta.recycle();

+ 0
- 4
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/ScrollListener.java 查看文件

@@ -23,10 +23,6 @@ public class ScrollListener implements ScrollViewDelegate.OnScrollListener {
23 23
 
24 24
     @Override
25 25
     public boolean onTouch(MotionEvent event) {
26
-        return handleTouch(event);
27
-    }
28
-
29
-    private boolean handleTouch(MotionEvent event) {
30 26
         CollapseAmount amount = collapseCalculator.calculate(event);
31 27
         if (amount.canCollapse()) {
32 28
             scrollListener.onScroll(amount.get());

+ 0
- 1
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/ScrollViewDelegate.java 查看文件

@@ -21,7 +21,6 @@ public class ScrollViewDelegate implements View.OnTouchListener {
21 21
 
22 22
     public void onScrollViewAdded(ScrollView scrollView) {
23 23
         this.scrollView = scrollView;
24
-        this.scrollView.setScrollbarFadingEnabled(false);
25 24
         listener.onScrollViewAdded(this.scrollView);
26 25
     }
27 26