Browse Source

Animate fab in and out when screen changes

Guy Carmeli 8 years ago
parent
commit
1142b437d8

+ 11
- 0
android/app/src/main/java/com/reactnativenavigation/events/ScreenChangedEvent.java View File

1
 package com.reactnativenavigation.events;
1
 package com.reactnativenavigation.events;
2
 
2
 
3
+import com.reactnativenavigation.params.ScreenParams;
4
+
3
 public class ScreenChangedEvent implements Event {
5
 public class ScreenChangedEvent implements Event {
4
     public static final String TYPE = "ScreenChangedEvent";
6
     public static final String TYPE = "ScreenChangedEvent";
7
+    private ScreenParams screenParams;
8
+
9
+    public ScreenChangedEvent(ScreenParams screenParams) {
10
+        this.screenParams = screenParams;
11
+    }
12
+
13
+    public ScreenParams getScreenParams() {
14
+        return screenParams;
15
+    }
5
 
16
 
6
     @Override
17
     @Override
7
     public String getType() {
18
     public String getType() {

+ 14
- 20
android/app/src/main/java/com/reactnativenavigation/layouts/BottomTabsLayout.java View File

8
 
8
 
9
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
9
 import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
10
 import com.reactnativenavigation.NavigationApplication;
10
 import com.reactnativenavigation.NavigationApplication;
11
+import com.reactnativenavigation.events.EventBus;
12
+import com.reactnativenavigation.events.ScreenChangedEvent;
11
 import com.reactnativenavigation.params.ActivityParams;
13
 import com.reactnativenavigation.params.ActivityParams;
12
-import com.reactnativenavigation.params.FabParams;
13
 import com.reactnativenavigation.params.ScreenParams;
14
 import com.reactnativenavigation.params.ScreenParams;
14
 import com.reactnativenavigation.params.SideMenuParams;
15
 import com.reactnativenavigation.params.SideMenuParams;
15
 import com.reactnativenavigation.params.SnackbarParams;
16
 import com.reactnativenavigation.params.SnackbarParams;
52
         addScreenStacks();
53
         addScreenStacks();
53
         createSnackbarContainer();
54
         createSnackbarContainer();
54
         showInitialScreenStack();
55
         showInitialScreenStack();
55
-        showFab();
56
     }
56
     }
57
 
57
 
58
     private void createSideMenu() {
58
     private void createSideMenu() {
110
 
110
 
111
     private void showInitialScreenStack() {
111
     private void showInitialScreenStack() {
112
         showStackAndUpdateStyle(screenStacks[0]);
112
         showStackAndUpdateStyle(screenStacks[0]);
113
-    }
114
-
115
-    private void showFab() {
116
-        FabParams fabParams = getCurrentScreenStack().peek().getFabParams();
117
-        if (fabParams != null) {
118
-            snackbarAndFabContainer.showFab(fabParams);
119
-        }
113
+        EventBus.instance.post(new ScreenChangedEvent(screenStacks[0].peek().getScreenParams()));
120
     }
114
     }
121
 
115
 
122
     @Override
116
     @Override
207
     }
201
     }
208
 
202
 
209
     @Override
203
     @Override
210
-    public void push(ScreenParams screenParams) {
211
-        ScreenStack screenStack = getScreenStack(screenParams.getNavigatorId());
212
-        screenStack.push(screenParams, createScreenLayoutParams(screenParams));
204
+    public void push(ScreenParams params) {
205
+        ScreenStack screenStack = getScreenStack(params.getNavigatorId());
206
+        screenStack.push(params, createScreenLayoutParams(params));
213
         if (isCurrentStack(screenStack)) {
207
         if (isCurrentStack(screenStack)) {
214
-            bottomTabs.setStyleFromScreen(screenParams.styleParams);
208
+            bottomTabs.setStyleFromScreen(params.styleParams);
215
         }
209
         }
216
-        snackbarAndFabContainer.onScreenChange();
210
+        EventBus.instance.post(new ScreenChangedEvent(params));
217
     }
211
     }
218
 
212
 
219
     @Override
213
     @Override
220
-    public void pop(ScreenParams screenParams) {
221
-        getCurrentScreenStack().pop(screenParams.animateScreenTransitions, new ScreenStack.OnScreenPop() {
214
+    public void pop(ScreenParams params) {
215
+        getCurrentScreenStack().pop(params.animateScreenTransitions, new ScreenStack.OnScreenPop() {
222
             @Override
216
             @Override
223
             public void onScreenPopAnimationEnd() {
217
             public void onScreenPopAnimationEnd() {
224
                 setBottomTabsStyleFromCurrentScreen();
218
                 setBottomTabsStyleFromCurrentScreen();
225
             }
219
             }
226
         });
220
         });
227
-        snackbarAndFabContainer.onScreenChange();
221
+        EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
228
     }
222
     }
229
 
223
 
230
     @Override
224
     @Override
231
     public void popToRoot(ScreenParams params) {
225
     public void popToRoot(ScreenParams params) {
232
         getCurrentScreenStack().popToRoot(params.animateScreenTransitions);
226
         getCurrentScreenStack().popToRoot(params.animateScreenTransitions);
233
         setBottomTabsStyleFromCurrentScreen();
227
         setBottomTabsStyleFromCurrentScreen();
234
-        snackbarAndFabContainer.onScreenChange();
228
+        EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
235
     }
229
     }
236
 
230
 
237
     @Override
231
     @Override
246
         screenStacks[currentStackIndex] = newStack;
240
         screenStacks[currentStackIndex] = newStack;
247
 
241
 
248
         bottomTabs.setStyleFromScreen(params.styleParams);
242
         bottomTabs.setStyleFromScreen(params.styleParams);
249
-        snackbarAndFabContainer.onScreenChange();
243
+        EventBus.instance.post(new ScreenChangedEvent(params));
250
     }
244
     }
251
 
245
 
252
     @Override
246
     @Override
264
     public boolean onTabSelected(int position, boolean wasSelected) {
258
     public boolean onTabSelected(int position, boolean wasSelected) {
265
         hideCurrentStack();
259
         hideCurrentStack();
266
         showNewStack(position);
260
         showNewStack(position);
267
-        snackbarAndFabContainer.onScreenChange();
261
+        EventBus.instance.post(new ScreenChangedEvent(getCurrentScreenStack().peek().getScreenParams()));
268
         return true;
262
         return true;
269
     }
263
     }
270
 
264
 

+ 6
- 4
android/app/src/main/java/com/reactnativenavigation/layouts/SingleScreenLayout.java View File

6
 import android.widget.RelativeLayout;
6
 import android.widget.RelativeLayout;
7
 
7
 
8
 import com.reactnativenavigation.NavigationApplication;
8
 import com.reactnativenavigation.NavigationApplication;
9
+import com.reactnativenavigation.events.EventBus;
10
+import com.reactnativenavigation.events.ScreenChangedEvent;
9
 import com.reactnativenavigation.params.ScreenParams;
11
 import com.reactnativenavigation.params.ScreenParams;
10
 import com.reactnativenavigation.params.SideMenuParams;
12
 import com.reactnativenavigation.params.SideMenuParams;
11
 import com.reactnativenavigation.params.SnackbarParams;
13
 import com.reactnativenavigation.params.SnackbarParams;
109
     public void push(ScreenParams params) {
111
     public void push(ScreenParams params) {
110
         LayoutParams lp = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
112
         LayoutParams lp = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
111
         stack.push(params, lp);
113
         stack.push(params, lp);
112
-        snackbarAndFabContainer.onScreenChange();
114
+        EventBus.instance.post(new ScreenChangedEvent(params));
113
     }
115
     }
114
 
116
 
115
     @Override
117
     @Override
116
     public void pop(ScreenParams params) {
118
     public void pop(ScreenParams params) {
117
         stack.pop(params.animateScreenTransitions);
119
         stack.pop(params.animateScreenTransitions);
118
-        snackbarAndFabContainer.onScreenChange();
120
+        EventBus.instance.post(new ScreenChangedEvent(stack.peek().getScreenParams()));
119
     }
121
     }
120
 
122
 
121
     @Override
123
     @Override
122
     public void popToRoot(ScreenParams params) {
124
     public void popToRoot(ScreenParams params) {
123
         stack.popToRoot(params.animateScreenTransitions);
125
         stack.popToRoot(params.animateScreenTransitions);
124
-        snackbarAndFabContainer.onScreenChange();
126
+        EventBus.instance.post(new ScreenChangedEvent(stack.peek().getScreenParams()));
125
     }
127
     }
126
 
128
 
127
     @Override
129
     @Override
128
     public void newStack(ScreenParams params) {
130
     public void newStack(ScreenParams params) {
129
         RelativeLayout parent = sideMenu == null ? this : sideMenu.getContentContainer();
131
         RelativeLayout parent = sideMenu == null ? this : sideMenu.getContentContainer();
130
         createStack(parent);
132
         createStack(parent);
131
-        snackbarAndFabContainer.onScreenChange();
133
+        EventBus.instance.post(new ScreenChangedEvent(params));
132
     }
134
     }
133
 
135
 
134
     @Override
136
     @Override

+ 2
- 1
android/app/src/main/java/com/reactnativenavigation/screens/ContentViewPagerAdapter.java View File

41
     }
41
     }
42
 
42
 
43
     private void sendScreenChangeBroadcast() {
43
     private void sendScreenChangeBroadcast() {
44
-        EventBus.instance.post(new ScreenChangedEvent());
44
+        // TODO Send navigatorParams to native. -guyca
45
+        EventBus.instance.post(new ScreenChangedEvent(null));
45
     }
46
     }
46
 
47
 
47
     private void sendTabSelectedEventToJs() {
48
     private void sendTabSelectedEventToJs() {

+ 2
- 3
android/app/src/main/java/com/reactnativenavigation/screens/Screen.java View File

9
 import android.widget.RelativeLayout;
9
 import android.widget.RelativeLayout;
10
 
10
 
11
 import com.reactnativenavigation.animation.VisibilityAnimator;
11
 import com.reactnativenavigation.animation.VisibilityAnimator;
12
-import com.reactnativenavigation.params.FabParams;
13
 import com.reactnativenavigation.params.ScreenParams;
12
 import com.reactnativenavigation.params.ScreenParams;
14
 import com.reactnativenavigation.params.StyleParams;
13
 import com.reactnativenavigation.params.StyleParams;
15
 import com.reactnativenavigation.params.TitleBarButtonParams;
14
 import com.reactnativenavigation.params.TitleBarButtonParams;
137
         return screenParams.getNavigatorEventId();
136
         return screenParams.getNavigatorEventId();
138
     }
137
     }
139
 
138
 
140
-    public FabParams getFabParams() {
141
-        return screenParams.fabParams;
139
+    public ScreenParams getScreenParams() {
140
+        return screenParams;
142
     }
141
     }
143
 
142
 
144
     public void setTopBarVisible(boolean visible, boolean animate) {
143
     public void setTopBarVisible(boolean visible, boolean animate) {

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

31
     final int margin = (int) ViewUtils.convertDpToPixel(16);
31
     final int margin = (int) ViewUtils.convertDpToPixel(16);
32
     private final ArrayList<FloatingActionButton> actions;
32
     private final ArrayList<FloatingActionButton> actions;
33
 
33
 
34
-    public FloatingActionButtonCoordinator(CoordinatorLayout parent, FabParams params) {
34
+    public FloatingActionButtonCoordinator(CoordinatorLayout parent) {
35
         this.parent = parent;
35
         this.parent = parent;
36
-        this.params = params;
37
         actions = new ArrayList<>();
36
         actions = new ArrayList<>();
38
         crossFadeAnimationDuration = parent.getResources().getInteger(android.R.integer.config_shortAnimTime);
37
         crossFadeAnimationDuration = parent.getResources().getInteger(android.R.integer.config_shortAnimTime);
39
         actionSize = (int) ViewUtils.convertDpToPixel(40);
38
         actionSize = (int) ViewUtils.convertDpToPixel(40);
39
+    }
40
+
41
+    public void add(FabParams params) {
42
+        this.params = params;
40
         createCollapsedFab();
43
         createCollapsedFab();
41
         createExpendedFab();
44
         createExpendedFab();
42
         setStyle();
45
         setStyle();
46
+        show();
47
+    }
48
+
49
+    public void remove(final Runnable onComplete) {
50
+        if (parent.getChildCount() == 0) {
51
+            onComplete.run();
52
+            return;
53
+        }
54
+
55
+        removeFabFromScreen(expendedFab, new AnimatorListenerAdapter() {
56
+            @Override
57
+            public void onAnimationEnd(Animator animation) {
58
+                removeAllViews();
59
+                onComplete.run();
60
+            }
61
+        });
62
+        removeFabFromScreen(collapsedFab, null);
63
+        removeActionsFromScreen();
64
+    }
65
+
66
+    private void removeActionsFromScreen() {
67
+        for (FloatingActionButton action : actions) {
68
+            action.animate()
69
+                    .alpha(0)
70
+                    .scaleX(0)
71
+                    .scaleY(0)
72
+                    .setDuration(crossFadeAnimationDuration)
73
+                    .start();
74
+        }
75
+    }
76
+
77
+    private void removeFabFromScreen(FloatingActionButton fab, AnimatorListenerAdapter animationListener) {
78
+        fab.animate()
79
+                .alpha(0)
80
+                .scaleX(0)
81
+                .scaleY(0)
82
+                .setDuration(crossFadeAnimationDuration)
83
+                .setListener(animationListener)
84
+                .start();
85
+    }
86
+
87
+    private void removeAllViews() {
88
+        parent.removeView(collapsedFab);
89
+        parent.removeView(expendedFab);
90
+        collapsedFab = null;
91
+        expendedFab = null;
92
+        for (FloatingActionButton action : actions) {
93
+            parent.removeView(action);
94
+        }
95
+        actions.clear();
43
     }
96
     }
44
 
97
 
45
     private void createCollapsedFab() {
98
     private void createCollapsedFab() {
127
         expendedFab.setBackgroundTintList(ColorStateList.valueOf(params.backgroundColor.getColor()));
180
         expendedFab.setBackgroundTintList(ColorStateList.valueOf(params.backgroundColor.getColor()));
128
     }
181
     }
129
 
182
 
130
-    public void show() {
131
-
183
+    private void show() {
184
+        collapsedFab.setScaleX(0);
185
+        collapsedFab.setScaleY(0);
186
+        collapsedFab.animate()
187
+                .alpha(1)
188
+                .scaleX(1)
189
+                .scaleY(1)
190
+                .setDuration(crossFadeAnimationDuration)
191
+                .start();
132
     }
192
     }
133
 
193
 
134
     private void showActions() {
194
     private void showActions() {

+ 27
- 15
android/app/src/main/java/com/reactnativenavigation/views/SnackbarAndFabContainer.java View File

1
 package com.reactnativenavigation.views;
1
 package com.reactnativenavigation.views;
2
 
2
 
3
 import android.content.Context;
3
 import android.content.Context;
4
-import android.support.annotation.NonNull;
5
 import android.support.design.widget.CoordinatorLayout;
4
 import android.support.design.widget.CoordinatorLayout;
6
 
5
 
7
 import com.reactnativenavigation.events.Event;
6
 import com.reactnativenavigation.events.Event;
8
 import com.reactnativenavigation.events.EventBus;
7
 import com.reactnativenavigation.events.EventBus;
9
 import com.reactnativenavigation.events.ScreenChangedEvent;
8
 import com.reactnativenavigation.events.ScreenChangedEvent;
10
 import com.reactnativenavigation.events.Subscriber;
9
 import com.reactnativenavigation.events.Subscriber;
11
-import com.reactnativenavigation.params.FabParams;
10
+import com.reactnativenavigation.params.ScreenParams;
12
 import com.reactnativenavigation.params.SnackbarParams;
11
 import com.reactnativenavigation.params.SnackbarParams;
13
 
12
 
14
 public class SnackbarAndFabContainer extends CoordinatorLayout implements Snakbar.OnDismissListener, Subscriber{
13
 public class SnackbarAndFabContainer extends CoordinatorLayout implements Snakbar.OnDismissListener, Subscriber{
15
     private Snakbar snakbar;
14
     private Snakbar snakbar;
16
-    private FloatingActionButtonCoordinator actionButtonCoordinator;
15
+    private FloatingActionButtonCoordinator fabCoordinator;
17
 
16
 
18
     public SnackbarAndFabContainer(Context context) {
17
     public SnackbarAndFabContainer(Context context) {
19
         super(context);
18
         super(context);
19
+        fabCoordinator = new FloatingActionButtonCoordinator(this);
20
         EventBus.instance.register(this);
20
         EventBus.instance.register(this);
21
     }
21
     }
22
 
22
 
25
         snakbar.show();
25
         snakbar.show();
26
     }
26
     }
27
 
27
 
28
-    public void onScreenChange() {
29
-        if (snakbar != null) {
30
-            snakbar.dismiss();
31
-            snakbar = null;
32
-        }
33
-    }
34
-
35
     @Override
28
     @Override
36
     public void onDismiss(Snakbar snakbar) {
29
     public void onDismiss(Snakbar snakbar) {
37
         if (this.snakbar == snakbar) {
30
         if (this.snakbar == snakbar) {
43
         EventBus.instance.unregister(this);
36
         EventBus.instance.unregister(this);
44
     }
37
     }
45
 
38
 
46
-    public void showFab(@NonNull FabParams fabParams) {
47
-        actionButtonCoordinator = new FloatingActionButtonCoordinator(this, fabParams);
48
-    }
49
-
50
     @Override
39
     @Override
51
     public void onEvent(Event event) {
40
     public void onEvent(Event event) {
52
         if (event.getType() == ScreenChangedEvent.TYPE) {
41
         if (event.getType() == ScreenChangedEvent.TYPE) {
53
-            onScreenChange();
42
+            onScreenChange(((ScreenChangedEvent) event).getScreenParams());
43
+        }
44
+    }
45
+
46
+    private void onScreenChange(ScreenParams screenParams) {
47
+        dismissSnackbar();
48
+        updateFab(screenParams);
49
+    }
50
+
51
+    private void dismissSnackbar() {
52
+        if (snakbar != null) {
53
+            snakbar.dismiss();
54
+            snakbar = null;
54
         }
55
         }
55
     }
56
     }
57
+
58
+    private void updateFab(final ScreenParams screenParams) {
59
+        fabCoordinator.remove(new Runnable() {
60
+            @Override
61
+            public void run() {
62
+                if (screenParams.fabParams != null) {
63
+                    fabCoordinator.add(screenParams.fabParams);
64
+                }
65
+            }
66
+        });
67
+    }
56
 }
68
 }