|
@@ -1,12 +1,15 @@
|
1
|
1
|
package com.reactnativenavigation.presentation;
|
2
|
2
|
|
3
|
3
|
|
|
4
|
+import android.animation.Animator;
|
|
5
|
+import android.animation.AnimatorListenerAdapter;
|
4
|
6
|
import android.view.Gravity;
|
5
|
7
|
import android.view.View;
|
6
|
8
|
import android.view.ViewGroup;
|
7
|
9
|
|
8
|
10
|
import com.reactnativenavigation.R;
|
9
|
11
|
import com.reactnativenavigation.parse.FabOptions;
|
|
12
|
+import com.reactnativenavigation.utils.UiUtils;
|
10
|
13
|
import com.reactnativenavigation.viewcontrollers.ViewController;
|
11
|
14
|
import com.reactnativenavigation.views.Fab;
|
12
|
15
|
import com.reactnativenavigation.views.FabMenu;
|
|
@@ -20,28 +23,28 @@ import static com.github.clans.fab.FloatingActionButton.SIZE_NORMAL;
|
20
|
23
|
import static com.reactnativenavigation.utils.ObjectUtils.perform;
|
21
|
24
|
|
22
|
25
|
public class FabPresenter {
|
|
26
|
+ private static final int DURATION = 200;
|
|
27
|
+
|
23
|
28
|
private ViewGroup viewGroup;
|
24
|
|
- private ViewController component;
|
25
|
29
|
|
26
|
30
|
private Fab fab;
|
27
|
31
|
private FabMenu fabMenu;
|
28
|
32
|
|
29
|
33
|
public void applyOptions(FabOptions options, @NonNull ViewController component, @NonNull ViewGroup viewGroup) {
|
30
|
34
|
this.viewGroup = viewGroup;
|
31
|
|
- this.component = component;
|
32
|
35
|
|
33
|
36
|
if (options.id.hasValue()) {
|
34
|
37
|
if (fabMenu != null && fabMenu.getFabId().equals(options.id.get())) {
|
35
|
38
|
fabMenu.bringToFront();
|
36
|
|
- applyFabMenuOptions(fabMenu, options);
|
37
|
|
- setParams(fabMenu, options);
|
|
39
|
+ applyFabMenuOptions(component, fabMenu, options);
|
|
40
|
+ setParams(component, fabMenu, options);
|
38
|
41
|
} else if (fab != null && fab.getFabId().equals(options.id.get())) {
|
39
|
42
|
fab.bringToFront();
|
40
|
|
- applyFabOptions(fab, options);
|
41
|
|
- setParams(fab, options);
|
|
43
|
+ setParams(component, fab, options);
|
|
44
|
+ applyFabOptions(component, fab, options);
|
42
|
45
|
fab.setOnClickListener(v -> component.sendOnNavigationButtonPressed(options.id.get()));
|
43
|
46
|
} else {
|
44
|
|
- createFab(options);
|
|
47
|
+ createFab(component, options);
|
45
|
48
|
}
|
46
|
49
|
} else {
|
47
|
50
|
removeFab();
|
|
@@ -51,35 +54,38 @@ public class FabPresenter {
|
51
|
54
|
|
52
|
55
|
public void mergeOptions(FabOptions options, @NonNull ViewController component, @NonNull ViewGroup viewGroup) {
|
53
|
56
|
this.viewGroup = viewGroup;
|
54
|
|
- this.component = component;
|
55
|
57
|
if (options.id.hasValue()) {
|
56
|
58
|
if (fabMenu != null && fabMenu.getFabId().equals(options.id.get())) {
|
57
|
59
|
mergeParams(fabMenu, options);
|
58
|
60
|
fabMenu.bringToFront();
|
59
|
|
- mergeFabMenuOptions(fabMenu, options);
|
|
61
|
+ mergeFabMenuOptions(component, fabMenu, options);
|
60
|
62
|
} else if (fab != null && fab.getFabId().equals(options.id.get())) {
|
61
|
63
|
mergeParams(fab, options);
|
62
|
64
|
fab.bringToFront();
|
63
|
|
- mergeFabOptions(fab, options);
|
|
65
|
+ mergeFabOptions(component, fab, options);
|
64
|
66
|
fab.setOnClickListener(v -> component.sendOnNavigationButtonPressed(options.id.get()));
|
65
|
67
|
} else {
|
66
|
|
- createFab(options);
|
|
68
|
+ createFab(component, options);
|
67
|
69
|
}
|
68
|
70
|
}
|
69
|
71
|
}
|
70
|
72
|
|
71
|
|
- private void createFab(FabOptions options) {
|
|
73
|
+ private void createFab(ViewController component, FabOptions options) {
|
72
|
74
|
if (options.actionsArray.size() > 0) {
|
73
|
75
|
fabMenu = new FabMenu(viewGroup.getContext(), options.id.get());
|
74
|
|
- setParams(fabMenu, options);
|
75
|
|
- applyFabMenuOptions(fabMenu, options);
|
|
76
|
+ setParams(component, fabMenu, options);
|
|
77
|
+ applyFabMenuOptions(component, fabMenu, options);
|
76
|
78
|
viewGroup.addView(fabMenu);
|
77
|
79
|
} else {
|
78
|
80
|
fab = new Fab(viewGroup.getContext(), options.id.get());
|
79
|
|
- setParams(fab, options);
|
80
|
|
- applyFabOptions(fab, options);
|
81
|
|
- fab.setOnClickListener(v -> component.sendOnNavigationButtonPressed(options.id.get()));
|
|
81
|
+ setParams(component, fab, options);
|
|
82
|
+ applyFabOptions(component, fab, options);
|
82
|
83
|
viewGroup.addView(fab);
|
|
84
|
+ fab.setOnClickListener(v -> component.sendOnNavigationButtonPressed(options.id.get()));
|
|
85
|
+ UiUtils.doOnLayout(fab, () -> {
|
|
86
|
+ fab.setPivotX(fab.getWidth() / 2f);
|
|
87
|
+ fab.setPivotY(fab.getHeight() / 2f);
|
|
88
|
+ });
|
83
|
89
|
}
|
84
|
90
|
}
|
85
|
91
|
|
|
@@ -93,18 +99,32 @@ public class FabPresenter {
|
93
|
99
|
|
94
|
100
|
private void removeFab() {
|
95
|
101
|
if (fab != null) {
|
96
|
|
- fab.hide(true);
|
97
|
|
- viewGroup.removeView(fab);
|
98
|
|
- fab = null;
|
|
102
|
+ animateHide(() -> {
|
|
103
|
+ viewGroup.removeView(fab);
|
|
104
|
+ fab = null;
|
|
105
|
+ });
|
99
|
106
|
}
|
100
|
107
|
}
|
101
|
108
|
|
102
|
|
- private void setParams(View fab, FabOptions options) {
|
|
109
|
+ public void animateHide(Runnable onAnimationEnd) {
|
|
110
|
+ fab.animate()
|
|
111
|
+ .scaleX(0f)
|
|
112
|
+ .scaleY(0f)
|
|
113
|
+ .setDuration(DURATION)
|
|
114
|
+ .setListener(new AnimatorListenerAdapter() {
|
|
115
|
+ @Override
|
|
116
|
+ public void onAnimationEnd(Animator animation) {
|
|
117
|
+ onAnimationEnd.run();
|
|
118
|
+ }
|
|
119
|
+ });
|
|
120
|
+ }
|
|
121
|
+
|
|
122
|
+ private void setParams(ViewController component, View fab, FabOptions options) {
|
103
|
123
|
CoordinatorLayout.LayoutParams lp = new CoordinatorLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
|
104
|
124
|
lp.rightMargin = (int) viewGroup.getContext().getResources().getDimension(R.dimen.margin);
|
105
|
125
|
lp.leftMargin = (int) viewGroup.getContext().getResources().getDimension(R.dimen.margin);
|
106
|
|
- lp.bottomMargin = (int) viewGroup.getContext().getResources().getDimension(R.dimen.margin);
|
107
|
|
- fab.setTag(R.id.fab_bottom_margin, lp.bottomMargin);
|
|
126
|
+ lp.bottomMargin = component.getBottomInset() + (int) viewGroup.getContext().getResources().getDimension(R.dimen.margin);
|
|
127
|
+ fab.setTag(R.id.fab_bottom_margin, (int) viewGroup.getContext().getResources().getDimension(R.dimen.margin));
|
108
|
128
|
lp.gravity = Gravity.BOTTOM;
|
109
|
129
|
if (options.alignHorizontally.hasValue()) {
|
110
|
130
|
if ("right".equals(options.alignHorizontally.get())) {
|
|
@@ -140,12 +160,22 @@ public class FabPresenter {
|
140
|
160
|
fab.setLayoutParams(lp);
|
141
|
161
|
}
|
142
|
162
|
|
143
|
|
- private void applyFabOptions(Fab fab, FabOptions options) {
|
|
163
|
+ private void applyFabOptions(ViewController component, Fab fab, FabOptions options) {
|
144
|
164
|
if (options.visible.isTrueOrUndefined()) {
|
145
|
|
- fab.show(true);
|
|
165
|
+ fab.setScaleX(0.6f);
|
|
166
|
+ fab.setScaleY(0.6f);
|
|
167
|
+ fab.animate()
|
|
168
|
+ .scaleX(1f)
|
|
169
|
+ .scaleY(1f)
|
|
170
|
+ .setDuration(DURATION)
|
|
171
|
+ .start();
|
146
|
172
|
}
|
147
|
173
|
if (options.visible.isFalse()) {
|
148
|
|
- fab.hide(true);
|
|
174
|
+ fab.animate()
|
|
175
|
+ .scaleX(0f)
|
|
176
|
+ .scaleY(0f)
|
|
177
|
+ .setDuration(DURATION)
|
|
178
|
+ .start();
|
149
|
179
|
}
|
150
|
180
|
if (options.backgroundColor.hasValue()) {
|
151
|
181
|
fab.setColorNormal(options.backgroundColor.get());
|
|
@@ -170,7 +200,7 @@ public class FabPresenter {
|
170
|
200
|
}
|
171
|
201
|
}
|
172
|
202
|
|
173
|
|
- private void mergeFabOptions(Fab fab, FabOptions options) {
|
|
203
|
+ private void mergeFabOptions(ViewController component, Fab fab, FabOptions options) {
|
174
|
204
|
if (options.visible.isTrue()) {
|
175
|
205
|
fab.show(true);
|
176
|
206
|
}
|
|
@@ -200,7 +230,7 @@ public class FabPresenter {
|
200
|
230
|
}
|
201
|
231
|
}
|
202
|
232
|
|
203
|
|
- private void applyFabMenuOptions(FabMenu fabMenu, FabOptions options) {
|
|
233
|
+ private void applyFabMenuOptions(ViewController component, FabMenu fabMenu, FabOptions options) {
|
204
|
234
|
if (options.visible.isTrueOrUndefined()) {
|
205
|
235
|
fabMenu.showMenuButton(true);
|
206
|
236
|
}
|
|
@@ -223,7 +253,7 @@ public class FabPresenter {
|
223
|
253
|
fabMenu.getActions().clear();
|
224
|
254
|
for (FabOptions fabOption : options.actionsArray) {
|
225
|
255
|
Fab fab = new Fab(viewGroup.getContext(), fabOption.id.get());
|
226
|
|
- applyFabOptions(fab, fabOption);
|
|
256
|
+ applyFabOptions(component, fab, fabOption);
|
227
|
257
|
fab.setOnClickListener(v -> component.sendOnNavigationButtonPressed(options.id.get()));
|
228
|
258
|
|
229
|
259
|
fabMenu.getActions().add(fab);
|
|
@@ -237,7 +267,7 @@ public class FabPresenter {
|
237
|
267
|
}
|
238
|
268
|
}
|
239
|
269
|
|
240
|
|
- private void mergeFabMenuOptions(FabMenu fabMenu, FabOptions options) {
|
|
270
|
+ private void mergeFabMenuOptions(ViewController component, FabMenu fabMenu, FabOptions options) {
|
241
|
271
|
if (options.visible.isTrue()) {
|
242
|
272
|
fabMenu.showMenuButton(true);
|
243
|
273
|
}
|
|
@@ -261,7 +291,7 @@ public class FabPresenter {
|
261
|
291
|
fabMenu.getActions().clear();
|
262
|
292
|
for (FabOptions fabOption : options.actionsArray) {
|
263
|
293
|
Fab fab = new Fab(viewGroup.getContext(), fabOption.id.get());
|
264
|
|
- applyFabOptions(fab, fabOption);
|
|
294
|
+ applyFabOptions(component, fab, fabOption);
|
265
|
295
|
fab.setOnClickListener(v -> component.sendOnNavigationButtonPressed(options.id.get()));
|
266
|
296
|
|
267
|
297
|
fabMenu.getActions().add(fab);
|