Browse Source

Getting there

* Animate actions
* Animate fab and actions with Snackbar
Guy Carmeli 8 years ago
parent
commit
80b1416cd5

+ 93
- 13
android/app/src/main/java/com/reactnativenavigation/views/FloatingActionButtonCoordinator.java View File

@@ -3,27 +3,38 @@ package com.reactnativenavigation.views;
3 3
 import android.animation.Animator;
4 4
 import android.animation.AnimatorListenerAdapter;
5 5
 import android.graphics.drawable.Drawable;
6
+import android.support.annotation.FloatRange;
7
+import android.support.annotation.NonNull;
6 8
 import android.support.design.widget.CoordinatorLayout;
7 9
 import android.support.design.widget.FloatingActionButton;
8 10
 import android.view.Gravity;
9 11
 import android.view.View;
10 12
 import android.view.ViewGroup;
11 13
 
14
+import com.reactnativenavigation.params.FabActionParams;
12 15
 import com.reactnativenavigation.params.FabParams;
13 16
 import com.reactnativenavigation.utils.ViewUtils;
14 17
 
18
+import java.util.ArrayList;
19
+
15 20
 public class FloatingActionButtonCoordinator {
16 21
 
22
+    private static final int INITIAL_EXPENDED_FAB_ROTATION = -90;
17 23
     private CoordinatorLayout parent;
18 24
     private FabParams params;
19
-    FloatingActionButton collapsedFab;
20
-    FloatingActionButton expendedFab;
21
-    final int crossFadeAnimationDuration;
25
+    private FloatingActionButton collapsedFab;
26
+    private FloatingActionButton expendedFab;
27
+    private final int crossFadeAnimationDuration;
28
+    private final int actionSize;
29
+    final int margin = (int) ViewUtils.convertDpToPixel(16);
30
+    private final ArrayList<FloatingActionButton> actions;
22 31
 
23 32
     public FloatingActionButtonCoordinator(CoordinatorLayout parent, FabParams params) {
24 33
         this.parent = parent;
25 34
         this.params = params;
35
+        actions = new ArrayList<>();
26 36
         crossFadeAnimationDuration = parent.getResources().getInteger(android.R.integer.config_shortAnimTime);
37
+        actionSize = (int) ViewUtils.convertDpToPixel(40);
27 38
         createCollapsedFab();
28 39
         createExpendedFab();
29 40
         setStyle();
@@ -31,19 +42,22 @@ public class FloatingActionButtonCoordinator {
31 42
 
32 43
     private void createCollapsedFab() {
33 44
         collapsedFab = createFab(params.collapsedIcon);
45
+        parent.addView(collapsedFab, createFabLayoutParams());
34 46
         collapsedFab.setOnClickListener(new View.OnClickListener() {
35 47
             @Override
36 48
             public void onClick(View v) {
37 49
                 hideCollapsed();
38 50
                 showExpended();
51
+                showActions();
39 52
             }
40 53
         });
41 54
     }
42 55
 
43 56
     private void createExpendedFab() {
44 57
         expendedFab = createFab(params.expendedIcon);
58
+        parent.addView(expendedFab, createFabLayoutParams());
45 59
         expendedFab.setVisibility(View.GONE);
46
-        expendedFab.setRotation(-90);
60
+        expendedFab.setRotation(INITIAL_EXPENDED_FAB_ROTATION);
47 61
         expendedFab.setOnClickListener(new View.OnClickListener() {
48 62
             @Override
49 63
             public void onClick(View v) {
@@ -53,6 +67,13 @@ public class FloatingActionButtonCoordinator {
53 67
         });
54 68
     }
55 69
 
70
+    private FloatingActionButton createFab(Drawable icon) {
71
+        FloatingActionButton fab = new FloatingActionButton(parent.getContext());
72
+        fab.setId(ViewUtils.generateViewId());
73
+        fab.setImageDrawable(icon);
74
+        return fab;
75
+    }
76
+
56 77
     private void hideCollapsed() {
57 78
         animateFab(collapsedFab, 0, 90);
58 79
     }
@@ -90,20 +111,12 @@ public class FloatingActionButtonCoordinator {
90 111
                 .start();
91 112
     }
92 113
 
93
-
94
-    private FloatingActionButton createFab(Drawable icon) {
95
-        FloatingActionButton fab = new FloatingActionButton(parent.getContext());
96
-        fab.setImageDrawable(icon);
97
-        parent.addView(fab, createFabLayoutParams());
98
-        return fab;
99
-    }
100
-
101 114
     private CoordinatorLayout.LayoutParams createFabLayoutParams() {
102 115
         final CoordinatorLayout.LayoutParams lp = new CoordinatorLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
103 116
         lp.gravity = Gravity.RIGHT | Gravity.BOTTOM;
104
-        final int margin = (int) ViewUtils.convertDpToPixel(16);
105 117
         lp.bottomMargin = margin;
106 118
         lp.rightMargin = margin;
119
+        lp.topMargin = margin;
107 120
         return lp;
108 121
     }
109 122
 
@@ -114,4 +127,71 @@ public class FloatingActionButtonCoordinator {
114 127
     public void show() {
115 128
 
116 129
     }
130
+
131
+    private void showActions() {
132
+        if (actions.size() > 0) {
133
+            return;
134
+        }
135
+
136
+        for (int i = 0; i < params.actions.size(); i++) {
137
+            FloatingActionButton action = createAction(i);
138
+            actions.add(action);
139
+            parent.addView(action);
140
+        }
141
+    }
142
+
143
+    private FloatingActionButton createAction(int index) {
144
+        FabActionParams actionParams = params.actions.get(index);
145
+        FloatingActionButton action = createFab(actionParams.icon);
146
+        action.setLayoutParams(createActionLayoutParams(index));
147
+     //   action.setAlpha(0);
148
+        return action;
149
+    }
150
+
151
+    @NonNull
152
+    private CoordinatorLayout.LayoutParams createActionLayoutParams(int actionIndex) {
153
+        CoordinatorLayout.LayoutParams lp = new CoordinatorLayout.LayoutParams(actionSize, actionSize);
154
+        lp.setAnchorId(expendedFab.getId());
155
+        lp.anchorGravity = Gravity.CENTER_HORIZONTAL;
156
+        lp.setBehavior(new ActionBehaviour(expendedFab, (actionIndex + 1) * (actionSize + margin / 2)));
157
+        return lp;
158
+    }
159
+
160
+    public static class ActionBehaviour extends CoordinatorLayout.Behavior<FloatingActionButton> {
161
+        private final int MAX_VALUE = 90;
162
+        private int dependencyId;
163
+        private float yStep;
164
+
165
+        public ActionBehaviour(View anchor, float yStep) {
166
+            this.yStep = yStep;
167
+            this.dependencyId = anchor.getId();
168
+        }
169
+
170
+        @Override
171
+        public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
172
+            return dependency.getId() == dependencyId;
173
+        }
174
+
175
+        @Override
176
+        public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
177
+            final float dependentValue = dependency.getRotation();
178
+            float fraction = calculateTransitionFraction(dependentValue);
179
+            child.setY(calculateY(parent, fraction));
180
+            child.setAlpha(calculateAlpha(fraction));
181
+            return true;
182
+        }
183
+
184
+        private float calculateAlpha(float fraction) {
185
+            return 1 * fraction;
186
+        }
187
+
188
+        private float calculateY(CoordinatorLayout parent, float fraction) {
189
+            return parent.findViewById(dependencyId).getY() - yStep * fraction;
190
+        }
191
+
192
+        @FloatRange(from=0.0, to=1.0)
193
+        private float calculateTransitionFraction(float dependentValue) {
194
+            return 1 - Math.abs(dependentValue / MAX_VALUE);
195
+        }
196
+    }
117 197
 }