Guy Carmeli 8 years ago
parent
commit
6933a61b3b

+ 4
- 4
android/app/src/main/java/com/reactnativenavigation/screens/CollapsingSingleScreen.java View File

35
     @Override
35
     @Override
36
     protected void createContent() {
36
     protected void createContent() {
37
         contentView = new ContentView(getContext(), screenParams.screenId, screenParams.navigationParams);
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
         addView(contentView, createLayoutParams());
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
                 new ScrollListener.OnScrollListener() {
45
                 new ScrollListener.OnScrollListener() {
46
                     @Override
46
                     @Override
47
                     public void onScroll(float amount) {
47
                     public void onScroll(float amount) {

+ 4
- 4
android/app/src/main/java/com/reactnativenavigation/views/ContentView.java View File

42
         viewMeasurer = new ViewMeasurer();
42
         viewMeasurer = new ViewMeasurer();
43
     }
43
     }
44
 
44
 
45
-    public void setupScrollDetection(ScrollListener scrollListener) {
45
+    public void setupCollapseDetection(ScrollListener scrollListener) {
46
         scrollViewDelegate = new ScrollViewDelegate(scrollListener);
46
         scrollViewDelegate = new ScrollViewDelegate(scrollListener);
47
     }
47
     }
48
 
48
 
90
         }
90
         }
91
     }
91
     }
92
 
92
 
93
-    private void onScrollViewAdded(ScrollView child) {
93
+    private void onScrollViewAdded(ScrollView scrollView) {
94
         if (scrollViewDelegate != null) {
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 View File

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

+ 13
- 23
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapseCalculator.java View File

5
 import android.view.MotionEvent;
5
 import android.view.MotionEvent;
6
 import android.widget.ScrollView;
6
 import android.widget.ScrollView;
7
 
7
 
8
-import com.reactnativenavigation.utils.ViewUtils;
9
-
10
 class CollapseCalculator {
8
 class CollapseCalculator {
11
     private float collapse;
9
     private float collapse;
12
     private MotionEvent previousTouchEvent;
10
     private MotionEvent previousTouchEvent;
18
     private boolean canExpend = false;
16
     private boolean canExpend = false;
19
     private CollapsingView view;
17
     private CollapsingView view;
20
     protected ScrollView scrollView;
18
     protected ScrollView scrollView;
21
-    private static float finalCollapsedTranslation;
22
 
19
 
23
     CollapseCalculator(final CollapsingView collapsingView) {
20
     CollapseCalculator(final CollapsingView collapsingView) {
24
         this.view = collapsingView;
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
     void setScrollView(ScrollView scrollView) {
24
     void setScrollView(ScrollView scrollView) {
38
     CollapseAmount calculate(MotionEvent event) {
29
     CollapseAmount calculate(MotionEvent event) {
39
         updateInitialTouchY(event);
30
         updateInitialTouchY(event);
40
         if (!isMoveEvent(event)) {
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
             return calculateCollapse(event);
36
             return calculateCollapse(event);
46
         } else {
37
         } else {
47
             previousCollapseY = -1;
38
             previousCollapseY = -1;
48
             previousTouchEvent = MotionEvent.obtain(event);
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
         checkCollapseLimits();
45
         checkCollapseLimits();
55
         ScrollDirection.Direction direction = getScrollDirection(event.getRawY());
46
         ScrollDirection.Direction direction = getScrollDirection(event.getRawY());
56
-        return isMoveEvent(event) &&
57
-               (isNotCollapsedOrExpended() ||
47
+        return isNotCollapsedOrExpended() ||
58
                 (canCollapse && isExpendedAndScrollingUp(direction)) ||
48
                 (canCollapse && isExpendedAndScrollingUp(direction)) ||
59
-                (canExpend && isCollapsedAndScrollingDown(direction)));
49
+                (canExpend && isCollapsedAndScrollingDown(direction));
60
     }
50
     }
61
 
51
 
62
     private ScrollDirection.Direction getScrollDirection(float y) {
52
     private ScrollDirection.Direction getScrollDirection(float y) {
72
     }
62
     }
73
 
63
 
74
     private void checkCollapseLimits() {
64
     private void checkCollapseLimits() {
75
-        float currentTopBarTranslation = view.getCurrentCollapseValue();
65
+        float currentCollapse = view.getCurrentCollapseValue();
76
         float finalExpendedTranslation = 0;
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
     private boolean calculateCanCollapse(float currentTopBarTranslation, float finalExpendedTranslation, float finalCollapsedTranslation) {
73
     private boolean calculateCanCollapse(float currentTopBarTranslation, float finalExpendedTranslation, float finalCollapsedTranslation) {
124
 
114
 
125
     private float calculateCollapse(float y) {
115
     private float calculateCollapse(float y) {
126
         float translation = y - previousCollapseY + view.getCurrentCollapseValue();
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
         final float expendedTranslation = 0;
120
         final float expendedTranslation = 0;
131
         if (translation > expendedTranslation) {
121
         if (translation > expendedTranslation) {

+ 20
- 4
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapsingContentViewMeasurer.java View File

1
 package com.reactnativenavigation.views.collapsingToolbar;
1
 package com.reactnativenavigation.views.collapsingToolbar;
2
 
2
 
3
+import com.reactnativenavigation.screens.Screen;
4
+import com.reactnativenavigation.utils.ViewUtils;
3
 import com.reactnativenavigation.views.utils.ViewMeasurer;
5
 import com.reactnativenavigation.views.utils.ViewMeasurer;
4
 
6
 
5
 public class CollapsingContentViewMeasurer extends ViewMeasurer {
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
     @Override
27
     @Override
12
     public int getMeasuredHeight(int heightMeasureSpec) {
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 View File

8
 import android.support.annotation.FloatRange;
8
 import android.support.annotation.FloatRange;
9
 import android.support.v4.widget.TextViewCompat;
9
 import android.support.v4.widget.TextViewCompat;
10
 import android.support.v7.widget.TintTypedArray;
10
 import android.support.v7.widget.TintTypedArray;
11
+import android.text.TextPaint;
11
 import android.view.animation.DecelerateInterpolator;
12
 import android.view.animation.DecelerateInterpolator;
12
 import android.view.animation.Interpolator;
13
 import android.view.animation.Interpolator;
13
 import android.widget.FrameLayout;
14
 import android.widget.FrameLayout;
25
     private TextView dummy;
26
     private TextView dummy;
26
     private String text;
27
     private String text;
27
     private Paint paint;
28
     private Paint paint;
28
-    private float initialY;
29
+    private float initialY = -1;
29
     private float currentY;
30
     private float currentY;
30
     private float collapseY;
31
     private float collapseY;
31
     private float collapseFraction;
32
     private float collapseFraction;
32
-    private int[] positionOnScreen;
33
     private Interpolator scaleInterpolator;
33
     private Interpolator scaleInterpolator;
34
     private float expendedTextSize;
34
     private float expendedTextSize;
35
     private float collapsedTextSize;
35
     private float collapsedTextSize;
62
     }
62
     }
63
 
63
 
64
     private void createTextPaint() {
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
         paint.setColor(Color.GREEN);
66
         paint.setColor(Color.GREEN);
67
         paint.setTextSize(expendedTextSize);
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
     public void setText(String text) {
70
     public void setText(String text) {
108
     @Override
96
     @Override
109
     protected void onDraw(Canvas canvas) {
97
     protected void onDraw(Canvas canvas) {
110
         super.onDraw(canvas);
98
         super.onDraw(canvas);
99
+        if (initialY == -1) {
100
+            calculateTextPosition();
101
+        }
111
         paint.setTextSize(linearInterpolation(expendedTextSize, collapsedTextSize, collapseFraction));
102
         paint.setTextSize(linearInterpolation(expendedTextSize, collapsedTextSize, collapseFraction));
112
         canvas.drawText(text, 0, currentY, paint);
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
     private float linearInterpolation(float from, float to, float fraction) {
114
     private float linearInterpolation(float from, float to, float fraction) {
116
         fraction = scaleInterpolator.getInterpolation(fraction);
115
         fraction = scaleInterpolator.getInterpolation(fraction);
117
         return from + (fraction * (to - from));
116
         return from + (fraction * (to - from));

+ 22
- 13
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapsingTopBar.java View File

5
 import android.widget.ScrollView;
5
 import android.widget.ScrollView;
6
 
6
 
7
 import com.reactnativenavigation.params.CollapsingTopBarParams;
7
 import com.reactnativenavigation.params.CollapsingTopBarParams;
8
+import com.reactnativenavigation.utils.ViewUtils;
8
 import com.reactnativenavigation.views.TitleBar;
9
 import com.reactnativenavigation.views.TitleBar;
9
 import com.reactnativenavigation.views.TopBar;
10
 import com.reactnativenavigation.views.TopBar;
10
 
11
 
11
 public class CollapsingTopBar extends TopBar implements CollapsingView {
12
 public class CollapsingTopBar extends TopBar implements CollapsingView {
12
-    private CollapsingToolBar collapsingToolBar;
13
+    private CollapsingTopBarBackground collapsingTopBarBackground;
13
     private ScrollListener scrollListener;
14
     private ScrollListener scrollListener;
15
+    private float finalCollapsedTranslation;
14
 
16
 
15
     public CollapsingTopBar(Context context, CollapsingTopBarParams params) {
17
     public CollapsingTopBar(Context context, CollapsingTopBarParams params) {
16
         super(context);
18
         super(context);
17
         createCollapsingTopBar(params);
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
     public void setScrollListener(ScrollListener scrollListener) {
29
     public void setScrollListener(ScrollListener scrollListener) {
22
     }
31
     }
23
 
32
 
24
     private void createCollapsingTopBar(CollapsingTopBarParams params) {
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
     @Override
39
     @Override
31
     protected TitleBar createTitleBar() {
40
     protected TitleBar createTitleBar() {
32
         return new CollapsingTitleBar(getContext(),
41
         return new CollapsingTitleBar(getContext(),
33
-                collapsingToolBar.getCollapsedTopBarHeight(),
42
+                collapsingTopBarBackground.getCollapsedTopBarHeight(),
34
                 scrollListener);
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
     public void collapse(float collapse) {
50
     public void collapse(float collapse) {
46
         setTranslationY(collapse);
51
         setTranslationY(collapse);
47
         ((CollapsingTitleBar) titleBar).collapse(collapse);
52
         ((CollapsingTitleBar) titleBar).collapse(collapse);
48
-        collapsingToolBar.collapse(collapse);
53
+        collapsingTopBarBackground.collapse(collapse);
49
     }
54
     }
50
 
55
 
51
     public void onScrollViewAdded(ScrollView scrollView) {
56
     public void onScrollViewAdded(ScrollView scrollView) {
54
 
59
 
55
     @Override
60
     @Override
56
     public float getFinalCollapseValue() {
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
     @Override
69
     @Override

android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapsingToolBar.java → android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapsingTopBarBackground.java View File

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

+ 0
- 4
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/ScrollListener.java View File

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

+ 0
- 1
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/ScrollViewDelegate.java View File

21
 
21
 
22
     public void onScrollViewAdded(ScrollView scrollView) {
22
     public void onScrollViewAdded(ScrollView scrollView) {
23
         this.scrollView = scrollView;
23
         this.scrollView = scrollView;
24
-        this.scrollView.setScrollbarFadingEnabled(false);
25
         listener.onScrollViewAdded(this.scrollView);
24
         listener.onScrollViewAdded(this.scrollView);
26
     }
25
     }
27
 
26