소스 검색

Collapse when scrolling header

Guy Carmeli 8 년 전
부모
커밋
2b7f9b4bb0

+ 5
- 1
android/app/src/main/java/com/reactnativenavigation/views/TopBar.java 파일 보기

@@ -41,7 +41,7 @@ public class TopBar extends AppBarLayout {
41 41
                                          LeftButtonOnClickListener leftButtonOnClickListener,
42 42
                                          String navigatorEventId, boolean overrideBackPressInJs) {
43 43
         titleBar = createTitleBar();
44
-        titleBarAndContextualMenuContainer.addView(titleBar, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
44
+        addTitleBar();
45 45
         addButtons(rightButtons, leftButton, leftButtonOnClickListener, navigatorEventId, overrideBackPressInJs);
46 46
     }
47 47
 
@@ -49,6 +49,10 @@ public class TopBar extends AppBarLayout {
49 49
         return new TitleBar(getContext());
50 50
     }
51 51
 
52
+    protected void addTitleBar() {
53
+        titleBarAndContextualMenuContainer.addView(titleBar, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
54
+    }
55
+
52 56
     private void addButtons(List<TitleBarButtonParams> rightButtons, TitleBarLeftButtonParams leftButton, LeftButtonOnClickListener leftButtonOnClickListener, String navigatorEventId, boolean overrideBackPressInJs) {
53 57
         titleBar.setRightButtons(rightButtons, navigatorEventId);
54 58
         titleBar.setLeftButton(leftButton, leftButtonOnClickListener, navigatorEventId, overrideBackPressInJs);

+ 25
- 7
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapsingTitleBar.java 파일 보기

@@ -4,6 +4,7 @@ import android.content.Context;
4 4
 import android.view.MotionEvent;
5 5
 import android.view.View;
6 6
 
7
+import com.reactnativenavigation.params.CollapsingTopBarParams;
7 8
 import com.reactnativenavigation.params.StyleParams;
8 9
 import com.reactnativenavigation.views.TitleBar;
9 10
 
@@ -11,38 +12,55 @@ public class CollapsingTitleBar extends TitleBar implements View.OnTouchListener
11 12
     private CollapsingTextView title;
12 13
     private int collapsedHeight;
13 14
     private final ScrollListener scrollListener;
15
+    private final CollapsingTopBarParams params;
14 16
 
15
-    public CollapsingTitleBar(Context context, int collapsedHeight, ScrollListener scrollListener) {
17
+    public CollapsingTitleBar(Context context, int collapsedHeight, ScrollListener scrollListener, CollapsingTopBarParams params) {
16 18
         super(context);
17 19
         this.collapsedHeight = collapsedHeight;
18 20
         this.scrollListener = scrollListener;
21
+        this.params = params;
19 22
         addCollapsingTitle();
20 23
         setOnTouchListener(this);
21 24
     }
22 25
 
23 26
     private void addCollapsingTitle() {
24
-        title = new CollapsingTextView(getContext(), collapsedHeight);
25
-        addView(title);
27
+        if (params.hasBackgroundImage()) {
28
+            title = new CollapsingTextView(getContext(), collapsedHeight);
29
+            addView(title);
30
+        }
26 31
     }
27 32
 
28 33
     @Override
29 34
     public void setTitle(CharSequence title) {
30
-        this.title.setText((String) title);
35
+        if (params.hasBackgroundImage()) {
36
+            this.title.setText((String) title);
37
+        } else {
38
+            super.setTitle(title);
39
+        }
31 40
     }
32 41
 
33 42
     @Override
34 43
     protected void setTitleTextColor(StyleParams params) {
35
-        title.setTextColor(params);
44
+        if (this.params.hasBackgroundImage()) {
45
+            title.setTextColor(params);
46
+        } else {
47
+            super.setTitleTextColor(params);
48
+        }
36 49
     }
37 50
 
38 51
     @Override
39 52
     protected void setSubtitleTextColor(StyleParams params) {
53
+        if (this.params.hasReactView()) {
54
+            super.setSubtitleTextColor(params);
55
+        }
40 56
     }
41 57
 
42 58
     public void collapse(float collapse) {
43
-        title.setTranslationY(0);
59
+        if (params.hasBackgroundImage()) {
60
+            title.setTranslationY(0);
61
+            title.collapseBy(collapse);
62
+        }
44 63
         setTranslationY(-collapse);
45
-        title.collapseBy(collapse);
46 64
     }
47 65
 
48 66
     @Override

+ 20
- 5
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapsingTopBar.java 파일 보기

@@ -4,6 +4,7 @@ import android.content.Context;
4 4
 import android.content.res.TypedArray;
5 5
 import android.os.Bundle;
6 6
 import android.view.View;
7
+import android.view.ViewGroup;
7 8
 import android.widget.ScrollView;
8 9
 
9 10
 import com.reactnativenavigation.params.CollapsingTopBarParams;
@@ -12,6 +13,9 @@ import com.reactnativenavigation.utils.ViewUtils;
12 13
 import com.reactnativenavigation.views.TitleBar;
13 14
 import com.reactnativenavigation.views.TopBar;
14 15
 
16
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
17
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
18
+
15 19
 public class CollapsingTopBar extends TopBar implements CollapsingView {
16 20
     private CollapsingTopBarBackground collapsingTopBarBackground;
17 21
     private CollapsingTopBarReactView header;
@@ -27,7 +31,6 @@ public class CollapsingTopBar extends TopBar implements CollapsingView {
27 31
         this.params = params;
28 32
         topBarHeight = calculateTopBarHeight();
29 33
         createBackgroundImage(params);
30
-        createReactView(params);
31 34
         calculateFinalCollapsedTranslation(params);
32 35
         viewCollapser = new ViewCollapser(this);
33 36
     }
@@ -36,7 +39,7 @@ public class CollapsingTopBar extends TopBar implements CollapsingView {
36 39
         ViewUtils.runOnPreDraw(this, new Runnable() {
37 40
             @Override
38 41
             public void run() {
39
-                if (params.hasBackgroundImage()) {
42
+                if (params.hasBackgroundImage() || params.hasReactView()) {
40 43
                     finalCollapsedTranslation = getCollapsedHeight() - getHeight();
41 44
                 } else {
42 45
                     finalCollapsedTranslation = -titleBar.getHeight();
@@ -70,7 +73,8 @@ public class CollapsingTopBar extends TopBar implements CollapsingView {
70 73
         if (params.hasReactView()) {
71 74
             header = new CollapsingTopBarReactView(getContext(),
72 75
                     params.reactViewId,
73
-                    new NavigationParams(Bundle.EMPTY));
76
+                    new NavigationParams(Bundle.EMPTY),
77
+                    scrollListener);
74 78
             LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, (int) ViewUtils.convertDpToPixel(params.reactViewHeight));
75 79
             titleBarAndContextualMenuContainer.addView(header, lp);
76 80
         }
@@ -78,15 +82,26 @@ public class CollapsingTopBar extends TopBar implements CollapsingView {
78 82
 
79 83
     @Override
80 84
     protected TitleBar createTitleBar() {
81
-        if (params.hasBackgroundImage()) {
85
+        if (params.hasBackgroundImage() || params.hasReactView()) {
86
+            createReactView(params);
82 87
             return new CollapsingTitleBar(getContext(),
83 88
                     getCollapsedHeight(),
84
-                    scrollListener);
89
+                    scrollListener,
90
+                    params);
85 91
         } else {
86 92
             return super.createTitleBar();
87 93
         }
88 94
     }
89 95
 
96
+    @Override
97
+    protected void addTitleBar() {
98
+        if (params.hasReactView()) {
99
+            titleBarAndContextualMenuContainer.addView(titleBar, new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
100
+        } else {
101
+            super.addTitleBar();
102
+        }
103
+    }
104
+
90 105
     @Override
91 106
     public void collapse(CollapseAmount amount) {
92 107
         viewCollapser.collapse(amount);

+ 86
- 1
android/app/src/main/java/com/reactnativenavigation/views/collapsingToolbar/CollapsingTopBarReactView.java 파일 보기

@@ -1,12 +1,97 @@
1 1
 package com.reactnativenavigation.views.collapsingToolbar;
2 2
 
3 3
 import android.content.Context;
4
+import android.support.v4.view.MotionEventCompat;
5
+import android.view.MotionEvent;
6
+import android.view.ViewConfiguration;
4 7
 
8
+import com.facebook.react.bridge.ReactContext;
9
+import com.facebook.react.uimanager.JSTouchDispatcher;
10
+import com.facebook.react.uimanager.UIManagerModule;
11
+import com.facebook.react.uimanager.events.EventDispatcher;
12
+import com.reactnativenavigation.NavigationApplication;
5 13
 import com.reactnativenavigation.params.NavigationParams;
6 14
 import com.reactnativenavigation.views.ContentView;
7 15
 
8 16
 public class CollapsingTopBarReactView extends ContentView {
9
-    public CollapsingTopBarReactView(Context context, String screenId, NavigationParams navigationParams) {
17
+    private ScrollListener listener;
18
+    private boolean mIsScrolling;
19
+    private int mTouchSlop;
20
+    private int touchDown = -1;
21
+    private final JSTouchDispatcher mJSTouchDispatcher = new JSTouchDispatcher(this);
22
+
23
+    public CollapsingTopBarReactView(Context context, String screenId, NavigationParams navigationParams, ScrollListener scrollListener) {
10 24
         super(context, screenId, navigationParams);
25
+        listener = scrollListener;
26
+        ViewConfiguration vc = ViewConfiguration.get(context);
27
+        mTouchSlop = vc.getScaledTouchSlop();
28
+    }
29
+
30
+    @Override
31
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
32
+        final int action = MotionEventCompat.getActionMasked(ev);
33
+        switch (action) {
34
+            case MotionEvent.ACTION_CANCEL:
35
+                releaseScroll(ev);
36
+                break;
37
+            case MotionEvent.ACTION_UP:
38
+                releaseScroll(ev);
39
+                break;
40
+            case MotionEvent.ACTION_DOWN:
41
+                onTouchDown(ev);
42
+                break;
43
+            case MotionEvent.ACTION_MOVE: {
44
+                if (mIsScrolling) {
45
+                    return true;
46
+                }
47
+                if (calculateDistanceY(ev) > mTouchSlop) {
48
+                    mIsScrolling = true;
49
+                    return true;
50
+                }
51
+                break;
52
+            }
53
+            default:
54
+                break;
55
+        }
56
+        return false;
57
+    }
58
+
59
+    private void onTouchDown(MotionEvent ev) {
60
+        if (touchDown == -1) {
61
+            touchDown = (int) ev.getRawY();
62
+        }
63
+        dispatchTouchEventToJs(ev);
64
+    }
65
+
66
+    private int calculateDistanceY(MotionEvent ev) {
67
+        return (int) Math.abs(ev.getRawY() - touchDown);
68
+    }
69
+
70
+    @Override
71
+    public boolean onTouchEvent(MotionEvent ev) {
72
+        listener.onTouch(ev);
73
+        int action = ev.getActionMasked();
74
+        switch (action) {
75
+            case MotionEvent.ACTION_UP:
76
+                releaseScroll(ev);
77
+                break;
78
+            case MotionEvent.ACTION_MOVE:
79
+                break;
80
+            default:
81
+                break;
82
+        }
83
+        return super.onTouchEvent(ev);
84
+    }
85
+
86
+    private void releaseScroll(MotionEvent ev) {
87
+        mIsScrolling = false;
88
+        touchDown = -1;
89
+        dispatchTouchEventToJs(ev);
90
+    }
91
+
92
+    private void dispatchTouchEventToJs(MotionEvent event) {
93
+        ReactContext reactContext = NavigationApplication.instance.getReactGateway().getReactInstanceManager().getCurrentReactContext();
94
+        EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
95
+        mJSTouchDispatcher.handleTouchEvent(event, eventDispatcher);
11 96
     }
12 97
 }