react-native-reanimated 3.0.0-rc.5 → 3.0.0-rc.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.cpp +97 -15
- package/Common/cpp/LayoutAnimations/LayoutAnimationsProxy.h +32 -8
- package/Common/cpp/NativeModules/NativeReanimatedModule.cpp +16 -1
- package/Common/cpp/NativeModules/NativeReanimatedModule.h +8 -1
- package/Common/cpp/NativeModules/NativeReanimatedModuleSpec.cpp +17 -0
- package/Common/cpp/NativeModules/NativeReanimatedModuleSpec.h +8 -0
- package/Common/cpp/Tools/RuntimeDecorator.cpp +2 -1
- package/android/src/fabric/java/com/swmansion/reanimated/NativeProxy.java +16 -25
- package/android/src/main/cpp/LayoutAnimations.cpp +42 -50
- package/android/src/main/cpp/LayoutAnimations.h +17 -3
- package/android/src/main/cpp/NativeProxy.cpp +54 -5
- package/android/src/main/java/com/swmansion/reanimated/NodesManager.java +1 -1
- package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/AnimationsManager.java +208 -223
- package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/LayoutAnimations.java +7 -5
- package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/NativeMethodsHolder.java +5 -3
- package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/ViewHierarchyObserver.java +1 -1
- package/android/src/paper/java/com/swmansion/reanimated/NativeProxy.java +20 -7
- package/android/src/reactNativeVersionPatch/nativeHierarchyManager/62/com/swmansion/reanimated/layoutReanimation/ReanimatedNativeHierarchyManager.java +8 -44
- package/android/src/reactNativeVersionPatch/nativeHierarchyManager/latest/com/swmansion/reanimated/layoutReanimation/ReanimatedNativeHierarchyManager.java +15 -61
- package/ios/LayoutReanimation/REAAnimationsManager.h +18 -8
- package/ios/LayoutReanimation/REAAnimationsManager.m +197 -162
- package/ios/LayoutReanimation/REAUIManager.mm +63 -70
- package/ios/native/NativeProxy.mm +49 -47
- package/lib/commonjs/createAnimatedComponent.js +26 -26
- package/lib/commonjs/createAnimatedComponent.js.map +1 -1
- package/lib/commonjs/reanimated2/NativeReanimated/NativeReanimated.js +4 -0
- package/lib/commonjs/reanimated2/NativeReanimated/NativeReanimated.js.map +1 -1
- package/lib/commonjs/reanimated2/core.js +9 -9
- package/lib/commonjs/reanimated2/core.js.map +1 -1
- package/lib/commonjs/reanimated2/globals.d.js.map +1 -1
- package/lib/commonjs/reanimated2/layoutReanimation/LayoutAnimationRepository.js +23 -62
- package/lib/commonjs/reanimated2/layoutReanimation/LayoutAnimationRepository.js.map +1 -1
- package/lib/module/createAnimatedComponent.js +27 -26
- package/lib/module/createAnimatedComponent.js.map +1 -1
- package/lib/module/reanimated2/NativeReanimated/NativeReanimated.js +4 -0
- package/lib/module/reanimated2/NativeReanimated/NativeReanimated.js.map +1 -1
- package/lib/module/reanimated2/core.js +7 -9
- package/lib/module/reanimated2/core.js.map +1 -1
- package/lib/module/reanimated2/globals.d.js.map +1 -1
- package/lib/module/reanimated2/layoutReanimation/LayoutAnimationRepository.js +22 -61
- package/lib/module/reanimated2/layoutReanimation/LayoutAnimationRepository.js.map +1 -1
- package/package.json +1 -1
- package/src/createAnimatedComponent.tsx +48 -39
- package/src/reanimated2/NativeReanimated/NativeReanimated.ts +15 -0
- package/src/reanimated2/core.ts +19 -10
- package/src/reanimated2/globals.d.ts +10 -6
- package/src/reanimated2/layoutReanimation/LayoutAnimationRepository.ts +24 -50
- package/lib/commonjs/reanimated2/layoutReanimation/defaultAnimations/Default.js +0 -55
- package/lib/commonjs/reanimated2/layoutReanimation/defaultAnimations/Default.js.map +0 -1
- package/lib/module/reanimated2/layoutReanimation/defaultAnimations/Default.js +0 -40
- package/lib/module/reanimated2/layoutReanimation/defaultAnimations/Default.js.map +0 -1
- package/src/reanimated2/layoutReanimation/defaultAnimations/Default.ts +0 -49
package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/AnimationsManager.java
CHANGED
|
@@ -16,9 +16,7 @@ import com.facebook.react.uimanager.IllegalViewOperationException;
|
|
|
16
16
|
import com.facebook.react.uimanager.PixelUtil;
|
|
17
17
|
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
|
18
18
|
import com.facebook.react.uimanager.RootView;
|
|
19
|
-
import com.facebook.react.uimanager.UIImplementation;
|
|
20
19
|
import com.facebook.react.uimanager.UIManagerModule;
|
|
21
|
-
import com.facebook.react.uimanager.ViewGroupManager;
|
|
22
20
|
import com.facebook.react.uimanager.ViewManager;
|
|
23
21
|
import com.swmansion.reanimated.Scheduler;
|
|
24
22
|
import java.lang.ref.WeakReference;
|
|
@@ -28,25 +26,17 @@ import java.util.HashSet;
|
|
|
28
26
|
import java.util.Map;
|
|
29
27
|
|
|
30
28
|
public class AnimationsManager implements ViewHierarchyObserver {
|
|
31
|
-
private static final String[] LAYOUT_KEYS = {
|
|
32
|
-
Snapshot.ORIGIN_X, Snapshot.ORIGIN_Y, Snapshot.WIDTH, Snapshot.HEIGHT
|
|
33
|
-
};
|
|
34
29
|
private WeakReference<Scheduler> mScheduler;
|
|
35
30
|
private ReactContext mContext;
|
|
36
|
-
private UIImplementation mUIImplementation;
|
|
37
31
|
private UIManagerModule mUIManager;
|
|
38
32
|
private NativeMethodsHolder mNativeMethodsHolder;
|
|
39
33
|
|
|
40
|
-
private HashMap<Integer,
|
|
41
|
-
private HashMap<Integer,
|
|
42
|
-
private HashSet<Integer>
|
|
43
|
-
private HashMap<Integer,
|
|
44
|
-
private HashMap<Integer, ViewManager> mParentViewManager;
|
|
45
|
-
private HashMap<Integer, View> mParent;
|
|
46
|
-
private HashMap<Integer, Runnable> mCallbacks;
|
|
47
|
-
private boolean mCleaningScheduled = false;
|
|
34
|
+
private HashMap<Integer, View> mExitingViews = new HashMap<>();
|
|
35
|
+
private HashMap<Integer, Integer> mExitingSubviewCountMap = new HashMap<>();
|
|
36
|
+
private HashSet<Integer> mAncestorsToRemove = new HashSet<>();
|
|
37
|
+
private HashMap<Integer, Runnable> mCallbacks = new HashMap<>();
|
|
48
38
|
private ReanimatedNativeHierarchyManager mReanimatedNativeHierarchyManager;
|
|
49
|
-
private boolean isCatalystInstanceDestroyed
|
|
39
|
+
private boolean isCatalystInstanceDestroyed;
|
|
50
40
|
|
|
51
41
|
public void setReanimatedNativeHierarchyManager(
|
|
52
42
|
ReanimatedNativeHierarchyManager reanimatedNativeHierarchyManager) {
|
|
@@ -61,26 +51,9 @@ public class AnimationsManager implements ViewHierarchyObserver {
|
|
|
61
51
|
mScheduler = new WeakReference<>(scheduler);
|
|
62
52
|
}
|
|
63
53
|
|
|
64
|
-
public
|
|
65
|
-
Inactive,
|
|
66
|
-
Appearing,
|
|
67
|
-
Disappearing,
|
|
68
|
-
Layout,
|
|
69
|
-
ToRemove;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
public AnimationsManager(
|
|
73
|
-
ReactContext context, UIImplementation uiImplementation, UIManagerModule uiManagerModule) {
|
|
54
|
+
public AnimationsManager(ReactContext context, UIManagerModule uiManagerModule) {
|
|
74
55
|
mContext = context;
|
|
75
|
-
mUIImplementation = uiImplementation;
|
|
76
56
|
mUIManager = uiManagerModule;
|
|
77
|
-
mStates = new HashMap<>();
|
|
78
|
-
mViewForTag = new HashMap<>();
|
|
79
|
-
mToRemove = new HashSet<>();
|
|
80
|
-
mViewManager = new HashMap<>();
|
|
81
|
-
mParentViewManager = new HashMap<>();
|
|
82
|
-
mParent = new HashMap();
|
|
83
|
-
mCallbacks = new HashMap<>();
|
|
84
57
|
isCatalystInstanceDestroyed = false;
|
|
85
58
|
}
|
|
86
59
|
|
|
@@ -88,41 +61,24 @@ public class AnimationsManager implements ViewHierarchyObserver {
|
|
|
88
61
|
isCatalystInstanceDestroyed = true;
|
|
89
62
|
mNativeMethodsHolder = null;
|
|
90
63
|
mContext = null;
|
|
91
|
-
mUIImplementation = null;
|
|
92
64
|
mUIManager = null;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
mViewManager = null;
|
|
97
|
-
mParent = null;
|
|
98
|
-
mParentViewManager = null;
|
|
65
|
+
mExitingViews = null;
|
|
66
|
+
mExitingSubviewCountMap = null;
|
|
67
|
+
mAncestorsToRemove = null;
|
|
99
68
|
mCallbacks = null;
|
|
100
69
|
}
|
|
101
70
|
|
|
102
71
|
@Override
|
|
103
|
-
public void onViewRemoval(View view, ViewGroup parent,
|
|
72
|
+
public void onViewRemoval(View view, ViewGroup parent, Runnable callback) {
|
|
104
73
|
if (isCatalystInstanceDestroyed) {
|
|
105
74
|
return;
|
|
106
75
|
}
|
|
107
76
|
Integer tag = view.getId();
|
|
108
|
-
HashMap<String, Object> currentValues = before.toCurrentMap();
|
|
109
|
-
ViewState state = mStates.get(view.getId());
|
|
110
|
-
|
|
111
|
-
if (state == ViewState.Disappearing || state == ViewState.ToRemove) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
77
|
mCallbacks.put(tag, callback);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
mToRemove.add(view.getId());
|
|
119
|
-
scheduleCleaning();
|
|
120
|
-
}
|
|
121
|
-
return;
|
|
78
|
+
|
|
79
|
+
if (!removeOrAnimateExitRecursive(view, parent, true)) {
|
|
80
|
+
removeView(view, parent);
|
|
122
81
|
}
|
|
123
|
-
mStates.put(tag, ViewState.Disappearing);
|
|
124
|
-
HashMap<String, Float> preparedValues = prepareDataForAnimationWorklet(currentValues, false);
|
|
125
|
-
mNativeMethodsHolder.startAnimationForTag(tag, "exiting", preparedValues);
|
|
126
82
|
}
|
|
127
83
|
|
|
128
84
|
@Override
|
|
@@ -130,27 +86,21 @@ public class AnimationsManager implements ViewHierarchyObserver {
|
|
|
130
86
|
if (isCatalystInstanceDestroyed) {
|
|
131
87
|
return;
|
|
132
88
|
}
|
|
89
|
+
|
|
90
|
+
if (!hasAnimationForTag(view.getId(), "entering")) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
133
94
|
Scheduler strongScheduler = mScheduler.get();
|
|
134
95
|
if (strongScheduler != null) {
|
|
135
96
|
strongScheduler.triggerUI();
|
|
136
97
|
}
|
|
137
|
-
|
|
138
|
-
mStates.put(view.getId(), ViewState.Inactive);
|
|
139
|
-
mViewForTag.put(view.getId(), view);
|
|
140
|
-
mViewManager.put(view.getId(), after.viewManager);
|
|
141
|
-
mParentViewManager.put(view.getId(), after.parentViewManager);
|
|
142
|
-
mParent.put(view.getId(), after.parent);
|
|
143
|
-
}
|
|
144
|
-
Integer tag = view.getId();
|
|
98
|
+
int tag = view.getId();
|
|
145
99
|
HashMap<String, Object> targetValues = after.toTargetMap();
|
|
146
|
-
ViewState state = mStates.get(view.getId());
|
|
147
100
|
|
|
148
|
-
if (
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
mNativeMethodsHolder.startAnimationForTag(tag, "entering", preparedValues);
|
|
152
|
-
}
|
|
153
|
-
return;
|
|
101
|
+
if (targetValues != null) {
|
|
102
|
+
HashMap<String, Float> preparedValues = prepareDataForAnimationWorklet(targetValues, true);
|
|
103
|
+
mNativeMethodsHolder.startAnimation(tag, "entering", preparedValues);
|
|
154
104
|
}
|
|
155
105
|
}
|
|
156
106
|
|
|
@@ -159,36 +109,32 @@ public class AnimationsManager implements ViewHierarchyObserver {
|
|
|
159
109
|
if (isCatalystInstanceDestroyed) {
|
|
160
110
|
return;
|
|
161
111
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
ViewState state = mStates.get(view.getId());
|
|
166
|
-
if (state == null
|
|
167
|
-
|| state == ViewState.Disappearing
|
|
168
|
-
|| state == ViewState.ToRemove
|
|
169
|
-
|| state == ViewState.Inactive) {
|
|
112
|
+
int tag = view.getId();
|
|
113
|
+
|
|
114
|
+
if (!hasAnimationForTag(tag, "layout")) {
|
|
170
115
|
return;
|
|
171
116
|
}
|
|
117
|
+
|
|
118
|
+
HashMap<String, Object> targetValues = after.toTargetMap();
|
|
119
|
+
HashMap<String, Object> startValues = before.toCurrentMap();
|
|
120
|
+
|
|
172
121
|
// If startValues are equal to targetValues it means that there was no UI Operation changing
|
|
173
122
|
// layout of the View. So dirtiness of that View is false positive
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
doNotStartLayout = false;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
if (doNotStartLayout) {
|
|
186
|
-
return;
|
|
123
|
+
boolean doNotStartLayout = true;
|
|
124
|
+
for (int i = 0; i < Snapshot.targetKeysToTransform.size(); ++i) {
|
|
125
|
+
double startV =
|
|
126
|
+
((Number) startValues.get(Snapshot.currentKeysToTransform.get(i))).doubleValue();
|
|
127
|
+
double targetV =
|
|
128
|
+
((Number) targetValues.get(Snapshot.targetKeysToTransform.get(i))).doubleValue();
|
|
129
|
+
if (startV != targetV) {
|
|
130
|
+
doNotStartLayout = false;
|
|
187
131
|
}
|
|
188
132
|
}
|
|
133
|
+
if (doNotStartLayout) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
189
136
|
|
|
190
137
|
// View must be in Layout state
|
|
191
|
-
mStates.put(view.getId(), ViewState.Layout);
|
|
192
138
|
HashMap<String, Float> preparedStartValues = prepareDataForAnimationWorklet(startValues, false);
|
|
193
139
|
HashMap<String, Float> preparedTargetValues =
|
|
194
140
|
prepareDataForAnimationWorklet(targetValues, true);
|
|
@@ -196,60 +142,41 @@ public class AnimationsManager implements ViewHierarchyObserver {
|
|
|
196
142
|
for (String key : preparedStartValues.keySet()) {
|
|
197
143
|
preparedValues.put(key, preparedStartValues.get(key));
|
|
198
144
|
}
|
|
199
|
-
mNativeMethodsHolder.
|
|
145
|
+
mNativeMethodsHolder.startAnimation(tag, "layout", preparedValues);
|
|
200
146
|
}
|
|
201
147
|
|
|
202
|
-
public void
|
|
203
|
-
|
|
204
|
-
if (state == ViewState.Inactive) {
|
|
205
|
-
mStates.put(tag, ViewState.Appearing);
|
|
206
|
-
}
|
|
148
|
+
public void progressLayoutAnimation(int tag, Map<String, Object> newStyle) {
|
|
149
|
+
View view = resolveView(tag);
|
|
207
150
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
mViewManager.get(tag),
|
|
212
|
-
mParentViewManager.get(tag),
|
|
213
|
-
mParent.get(tag).getId());
|
|
214
|
-
}
|
|
151
|
+
if (view == null) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
215
154
|
|
|
216
|
-
|
|
217
|
-
if (!cancelled) {
|
|
218
|
-
ViewState state = mStates.get(tag);
|
|
219
|
-
if (state == ViewState.Appearing) {
|
|
220
|
-
mStates.put(tag, ViewState.Layout);
|
|
221
|
-
}
|
|
155
|
+
ViewGroup parent = (ViewGroup) view.getParent();
|
|
222
156
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
mToRemove.add(tag);
|
|
226
|
-
scheduleCleaning();
|
|
227
|
-
}
|
|
157
|
+
if (parent == null) {
|
|
158
|
+
return;
|
|
228
159
|
}
|
|
160
|
+
|
|
161
|
+
ViewManager viewManager = resolveViewManager(tag);
|
|
162
|
+
ViewManager parentViewManager = resolveViewManager(parent.getId());
|
|
163
|
+
|
|
164
|
+
setNewProps(newStyle, view, viewManager, parentViewManager, parent.getId());
|
|
229
165
|
}
|
|
230
166
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if (
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
for (int tag : mToRemove) {
|
|
237
|
-
View view = mViewForTag.get(tag);
|
|
238
|
-
if (view == null) {
|
|
239
|
-
try {
|
|
240
|
-
view = mUIManager.resolveView(tag);
|
|
241
|
-
mViewForTag.put(tag, view);
|
|
242
|
-
} catch (IllegalViewOperationException ignored) {
|
|
243
|
-
continue;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
findRoot(view, roots);
|
|
167
|
+
public void endLayoutAnimation(int tag, boolean cancelled, boolean removeView) {
|
|
168
|
+
View exitingView = mExitingViews.get(tag);
|
|
169
|
+
if (exitingView != null && removeView) {
|
|
170
|
+
if (exitingView instanceof ViewGroup && mAncestorsToRemove.contains(tag)) {
|
|
171
|
+
cancelAnimationsInSubviews((ViewGroup) exitingView);
|
|
247
172
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
173
|
+
|
|
174
|
+
mExitingViews.remove(tag);
|
|
175
|
+
maybeDropAncestors(exitingView);
|
|
176
|
+
|
|
177
|
+
ViewGroup parent = (ViewGroup) exitingView.getParent();
|
|
178
|
+
if (parent != null) {
|
|
179
|
+
removeView(exitingView, parent);
|
|
253
180
|
}
|
|
254
181
|
}
|
|
255
182
|
}
|
|
@@ -267,8 +194,6 @@ public class AnimationsManager implements ViewHierarchyObserver {
|
|
|
267
194
|
}
|
|
268
195
|
out.append(" TAG:");
|
|
269
196
|
out.append(view.getId());
|
|
270
|
-
out.append(" STATE:");
|
|
271
|
-
out.append(this.mStates.get(view.getId()));
|
|
272
197
|
out.append(" CLASS:");
|
|
273
198
|
out.append(view.getClass().getSimpleName());
|
|
274
199
|
Log.v("rea", out.toString());
|
|
@@ -280,85 +205,6 @@ public class AnimationsManager implements ViewHierarchyObserver {
|
|
|
280
205
|
}
|
|
281
206
|
}
|
|
282
207
|
|
|
283
|
-
private void scheduleCleaning() {
|
|
284
|
-
if (mCleaningScheduled) return;
|
|
285
|
-
mCleaningScheduled = true;
|
|
286
|
-
WeakReference<AnimationsManager> animationsManagerWeakReference = new WeakReference<>(this);
|
|
287
|
-
mContext.runOnUiQueueThread(
|
|
288
|
-
() -> {
|
|
289
|
-
mCleaningScheduled = false;
|
|
290
|
-
AnimationsManager thiz = animationsManagerWeakReference.get();
|
|
291
|
-
if (thiz == null) {
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
removeLeftovers();
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
private void findRoot(View view, HashSet<Integer> roots) {
|
|
299
|
-
View currentView = view;
|
|
300
|
-
int lastToRemoveTag = -1;
|
|
301
|
-
while (currentView != null) {
|
|
302
|
-
ViewState state = mStates.get(currentView.getId());
|
|
303
|
-
if (state == ViewState.Disappearing) {
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
if (state == ViewState.ToRemove) {
|
|
307
|
-
lastToRemoveTag = currentView.getId();
|
|
308
|
-
}
|
|
309
|
-
if (currentView.getParent() instanceof View) {
|
|
310
|
-
currentView = (View) currentView.getParent();
|
|
311
|
-
} else {
|
|
312
|
-
break;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
if (lastToRemoveTag != -1) {
|
|
316
|
-
roots.add(lastToRemoveTag);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
private boolean dfs(View root, View view, HashSet<Integer> cands) {
|
|
321
|
-
if ((!cands.contains(view.getId())) && (mStates.containsKey(view.getId()))) {
|
|
322
|
-
return true;
|
|
323
|
-
}
|
|
324
|
-
boolean cannotStripe = false;
|
|
325
|
-
if (view instanceof ViewGroup && mViewManager.get(view.getId()) instanceof ViewGroupManager) {
|
|
326
|
-
ViewGroup vg = (ViewGroup) view;
|
|
327
|
-
ViewGroupManager vgm = (ViewGroupManager) mViewManager.get(vg.getId());
|
|
328
|
-
ArrayList<View> children = new ArrayList<>();
|
|
329
|
-
for (int i = 0; i < vgm.getChildCount(vg); ++i) {
|
|
330
|
-
children.add(vgm.getChildAt(vg, i));
|
|
331
|
-
}
|
|
332
|
-
for (View child : children) {
|
|
333
|
-
cannotStripe = cannotStripe || dfs(root, child, cands);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
if (!cannotStripe) {
|
|
338
|
-
View parentView = (View) view.getParent();
|
|
339
|
-
if (mCallbacks.containsKey(view.getId())) {
|
|
340
|
-
Runnable runnable = mCallbacks.get(view.getId());
|
|
341
|
-
mCallbacks.remove(view.getId());
|
|
342
|
-
runnable.run();
|
|
343
|
-
}
|
|
344
|
-
if (mParent.containsKey(view.getId())) {
|
|
345
|
-
ViewGroup parent = (ViewGroup) mParent.get(view.getId());
|
|
346
|
-
if (parent != null) {
|
|
347
|
-
parent.removeView(view);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
View curView = view;
|
|
351
|
-
mStates.remove(curView.getId());
|
|
352
|
-
mViewForTag.remove(curView.getId());
|
|
353
|
-
mViewManager.remove(curView.getId());
|
|
354
|
-
mParentViewManager.remove(curView.getId());
|
|
355
|
-
mParent.remove(curView.getId());
|
|
356
|
-
mNativeMethodsHolder.removeConfigForTag(curView.getId());
|
|
357
|
-
mToRemove.remove(view.getId());
|
|
358
|
-
}
|
|
359
|
-
return cannotStripe;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
208
|
public HashMap<String, Float> prepareDataForAnimationWorklet(
|
|
363
209
|
HashMap<String, Object> values, boolean isTargetValues) {
|
|
364
210
|
HashMap<String, Float> preparedValues = new HashMap<>();
|
|
@@ -449,7 +295,7 @@ public class AnimationsManager implements ViewHierarchyObserver {
|
|
|
449
295
|
} else if (value instanceof ReadableMap) {
|
|
450
296
|
propMap.putMap(key, (ReadableMap) value);
|
|
451
297
|
} else {
|
|
452
|
-
throw new IllegalStateException("Unknown type of animated value [Layout
|
|
298
|
+
throw new IllegalStateException("Unknown type of animated value [Layout Animations]");
|
|
453
299
|
}
|
|
454
300
|
}
|
|
455
301
|
|
|
@@ -512,8 +358,7 @@ public class AnimationsManager implements ViewHierarchyObserver {
|
|
|
512
358
|
+ parentTag
|
|
513
359
|
+ " as a parent, but its Manager doesn't implement IViewManagerWithChildren");
|
|
514
360
|
}
|
|
515
|
-
if (parentViewManagerWithChildren
|
|
516
|
-
&& !parentViewManagerWithChildren.needsCustomLayoutForChildren()) {
|
|
361
|
+
if (!parentViewManagerWithChildren.needsCustomLayoutForChildren()) {
|
|
517
362
|
viewToUpdate.layout(x, y, x + width, y + height);
|
|
518
363
|
}
|
|
519
364
|
} else {
|
|
@@ -521,7 +366,147 @@ public class AnimationsManager implements ViewHierarchyObserver {
|
|
|
521
366
|
}
|
|
522
367
|
}
|
|
523
368
|
|
|
369
|
+
public boolean hasAnimationForTag(int tag, String type) {
|
|
370
|
+
return mNativeMethodsHolder.hasAnimation(tag, type);
|
|
371
|
+
}
|
|
372
|
+
|
|
524
373
|
public boolean isLayoutAnimationEnabled() {
|
|
525
374
|
return mNativeMethodsHolder != null && mNativeMethodsHolder.isLayoutAnimationEnabled();
|
|
526
375
|
}
|
|
376
|
+
|
|
377
|
+
private boolean removeOrAnimateExitRecursive(View view, ViewGroup parent, boolean shouldRemove) {
|
|
378
|
+
int tag = view.getId();
|
|
379
|
+
boolean hasExitAnimation = hasAnimationForTag(tag, "exiting") || mExitingViews.containsKey(tag);
|
|
380
|
+
boolean hasAnimatedChildren = false;
|
|
381
|
+
shouldRemove = shouldRemove && !hasExitAnimation;
|
|
382
|
+
|
|
383
|
+
ArrayList<View> toBeRemoved = new ArrayList<>();
|
|
384
|
+
|
|
385
|
+
// we might want to keep this view around
|
|
386
|
+
// because one of the (children's) children
|
|
387
|
+
// has an exiting animation
|
|
388
|
+
if (view instanceof ViewGroup) {
|
|
389
|
+
ViewGroup viewGroup = (ViewGroup) view;
|
|
390
|
+
for (int i = viewGroup.getChildCount() - 1; i >= 0; i--) {
|
|
391
|
+
View child = viewGroup.getChildAt(i);
|
|
392
|
+
if (removeOrAnimateExitRecursive(child, viewGroup, shouldRemove)) {
|
|
393
|
+
hasAnimatedChildren = true;
|
|
394
|
+
} else if (shouldRemove) {
|
|
395
|
+
toBeRemoved.add(child);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
boolean wantAnimateExit = hasExitAnimation || hasAnimatedChildren;
|
|
401
|
+
|
|
402
|
+
if (hasExitAnimation) {
|
|
403
|
+
Snapshot before = new Snapshot(view, mReanimatedNativeHierarchyManager);
|
|
404
|
+
HashMap<String, Object> currentValues = before.toCurrentMap();
|
|
405
|
+
HashMap<String, Float> preparedValues = prepareDataForAnimationWorklet(currentValues, false);
|
|
406
|
+
if (!mExitingViews.containsKey(tag)) {
|
|
407
|
+
mExitingViews.put(tag, view);
|
|
408
|
+
registerExitingAncestors(view);
|
|
409
|
+
mNativeMethodsHolder.startAnimation(tag, "exiting", preparedValues);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
mNativeMethodsHolder.clearAnimationConfig(tag);
|
|
414
|
+
|
|
415
|
+
if (!wantAnimateExit) {
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (hasAnimatedChildren) {
|
|
420
|
+
mAncestorsToRemove.add(tag);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
for (View child : toBeRemoved) {
|
|
424
|
+
removeView(child, (ViewGroup) view);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
private void registerExitingAncestors(View view) {
|
|
431
|
+
View parent = (View) view.getParent();
|
|
432
|
+
while (parent != null && !(parent instanceof RootView)) {
|
|
433
|
+
int tag = parent.getId();
|
|
434
|
+
Integer previousValue = mExitingSubviewCountMap.get(tag);
|
|
435
|
+
int newValue = previousValue != null ? previousValue + 1 : 1;
|
|
436
|
+
mExitingSubviewCountMap.put(tag, newValue);
|
|
437
|
+
|
|
438
|
+
parent = (View) parent.getParent();
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
private void maybeDropAncestors(View exitingView) {
|
|
443
|
+
View parent = (View) exitingView.getParent();
|
|
444
|
+
while (parent != null && !(parent instanceof RootView)) {
|
|
445
|
+
View view = parent;
|
|
446
|
+
parent = (View) view.getParent();
|
|
447
|
+
int tag = view.getId();
|
|
448
|
+
Integer ancestorOfCount = mExitingSubviewCountMap.get(tag);
|
|
449
|
+
ancestorOfCount = ancestorOfCount != null ? ancestorOfCount - 1 : 0;
|
|
450
|
+
if (ancestorOfCount <= 0) {
|
|
451
|
+
if (mAncestorsToRemove.contains(tag)) {
|
|
452
|
+
mAncestorsToRemove.remove(tag);
|
|
453
|
+
if (!mExitingViews.containsKey(tag)) {
|
|
454
|
+
removeView(view, (ViewGroup) parent);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
mExitingSubviewCountMap.remove(tag);
|
|
458
|
+
} else {
|
|
459
|
+
mExitingSubviewCountMap.put(tag, ancestorOfCount);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
private void removeView(View view, ViewGroup parent) {
|
|
465
|
+
int tag = view.getId();
|
|
466
|
+
if (mCallbacks.containsKey(tag)) {
|
|
467
|
+
Runnable callback = mCallbacks.get(tag);
|
|
468
|
+
mCallbacks.remove(tag);
|
|
469
|
+
if (callback != null) {
|
|
470
|
+
callback.run();
|
|
471
|
+
}
|
|
472
|
+
} else {
|
|
473
|
+
mReanimatedNativeHierarchyManager.publicDropView(view);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
parent.removeView(view);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
private void cancelAnimationsInSubviews(ViewGroup view) {
|
|
480
|
+
for (int i = view.getChildCount() - 1; i >= 0; i--) {
|
|
481
|
+
View child = view.getChildAt(i);
|
|
482
|
+
|
|
483
|
+
if (mExitingViews.containsKey(child.getId())) {
|
|
484
|
+
endLayoutAnimation(child.getId(), true, true);
|
|
485
|
+
} else if (child instanceof ViewGroup && mAncestorsToRemove.contains(child.getId())) {
|
|
486
|
+
cancelAnimationsInSubviews((ViewGroup) child);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
private View resolveView(int tag) {
|
|
492
|
+
if (mExitingViews.containsKey(tag)) {
|
|
493
|
+
return mExitingViews.get(tag);
|
|
494
|
+
}
|
|
495
|
+
try {
|
|
496
|
+
return mUIManager.resolveView(tag);
|
|
497
|
+
} catch (IllegalViewOperationException e) {
|
|
498
|
+
// view has been removed already
|
|
499
|
+
e.printStackTrace();
|
|
500
|
+
return null;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
private ViewManager resolveViewManager(int tag) {
|
|
505
|
+
try {
|
|
506
|
+
return mReanimatedNativeHierarchyManager.resolveViewManager(tag);
|
|
507
|
+
} catch (Exception e) {
|
|
508
|
+
e.printStackTrace();
|
|
509
|
+
return null;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
527
512
|
}
|
package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/LayoutAnimations.java
CHANGED
|
@@ -29,29 +29,31 @@ public class LayoutAnimations {
|
|
|
29
29
|
// LayoutReanimation
|
|
30
30
|
public native void startAnimationForTag(int tag, String type, Map<String, String> values);
|
|
31
31
|
|
|
32
|
-
public native
|
|
32
|
+
public native boolean hasAnimationForTag(int tag, String type);
|
|
33
|
+
|
|
34
|
+
public native void clearAnimationConfigForTag(int tag);
|
|
33
35
|
|
|
34
36
|
public native boolean isLayoutAnimationEnabled();
|
|
35
37
|
|
|
36
|
-
private void
|
|
38
|
+
private void endLayoutAnimation(int tag, boolean cancelled, boolean removeView) {
|
|
37
39
|
ReactApplicationContext context = mContext.get();
|
|
38
40
|
if (context != null) {
|
|
39
41
|
context
|
|
40
42
|
.getNativeModule(ReanimatedModule.class)
|
|
41
43
|
.getNodesManager()
|
|
42
44
|
.getAnimationsManager()
|
|
43
|
-
.
|
|
45
|
+
.endLayoutAnimation(tag, cancelled, removeView);
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
private void
|
|
49
|
+
private void progressLayoutAnimation(int tag, Map<String, Object> newStyle) {
|
|
48
50
|
ReactApplicationContext context = mContext.get();
|
|
49
51
|
if (context != null) {
|
|
50
52
|
context
|
|
51
53
|
.getNativeModule(ReanimatedModule.class)
|
|
52
54
|
.getNodesManager()
|
|
53
55
|
.getAnimationsManager()
|
|
54
|
-
.
|
|
56
|
+
.progressLayoutAnimation(tag, newStyle);
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
}
|
package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/NativeMethodsHolder.java
CHANGED
|
@@ -3,9 +3,11 @@ package com.swmansion.reanimated.layoutReanimation;
|
|
|
3
3
|
import java.util.HashMap;
|
|
4
4
|
|
|
5
5
|
public interface NativeMethodsHolder {
|
|
6
|
-
|
|
6
|
+
void startAnimation(int tag, String type, HashMap<String, Float> values);
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
boolean hasAnimation(int tag, String type);
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
void clearAnimationConfig(int tag);
|
|
11
|
+
|
|
12
|
+
boolean isLayoutAnimationEnabled();
|
|
11
13
|
}
|
package/android/src/main/java/com/swmansion/reanimated/layoutReanimation/ViewHierarchyObserver.java
CHANGED
|
@@ -4,7 +4,7 @@ import android.view.View;
|
|
|
4
4
|
import android.view.ViewGroup;
|
|
5
5
|
|
|
6
6
|
public interface ViewHierarchyObserver {
|
|
7
|
-
void onViewRemoval(View view, ViewGroup parent,
|
|
7
|
+
void onViewRemoval(View view, ViewGroup parent, Runnable callback);
|
|
8
8
|
|
|
9
9
|
void onViewCreate(View view, ViewGroup parent, Snapshot after);
|
|
10
10
|
|
|
@@ -298,7 +298,7 @@ public class NativeProxy {
|
|
|
298
298
|
animationsManager.setNativeMethods(
|
|
299
299
|
new NativeMethodsHolder() {
|
|
300
300
|
@Override
|
|
301
|
-
public void
|
|
301
|
+
public void startAnimation(int tag, String type, HashMap<String, Float> values) {
|
|
302
302
|
LayoutAnimations LayoutAnimations = weakLayoutAnimations.get();
|
|
303
303
|
if (LayoutAnimations != null) {
|
|
304
304
|
HashMap<String, String> preparedValues = new HashMap<>();
|
|
@@ -310,16 +310,29 @@ public class NativeProxy {
|
|
|
310
310
|
}
|
|
311
311
|
|
|
312
312
|
@Override
|
|
313
|
-
public
|
|
314
|
-
LayoutAnimations
|
|
315
|
-
if (
|
|
316
|
-
|
|
313
|
+
public boolean isLayoutAnimationEnabled() {
|
|
314
|
+
LayoutAnimations layoutAnimations = weakLayoutAnimations.get();
|
|
315
|
+
if (layoutAnimations != null) {
|
|
316
|
+
return layoutAnimations.isLayoutAnimationEnabled();
|
|
317
317
|
}
|
|
318
|
+
return false;
|
|
318
319
|
}
|
|
319
320
|
|
|
320
321
|
@Override
|
|
321
|
-
public boolean
|
|
322
|
-
|
|
322
|
+
public boolean hasAnimation(int tag, String type) {
|
|
323
|
+
LayoutAnimations layoutAnimations = weakLayoutAnimations.get();
|
|
324
|
+
if (layoutAnimations != null) {
|
|
325
|
+
return layoutAnimations.hasAnimationForTag(tag, type);
|
|
326
|
+
}
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
@Override
|
|
331
|
+
public void clearAnimationConfig(int tag) {
|
|
332
|
+
LayoutAnimations layoutAnimations = weakLayoutAnimations.get();
|
|
333
|
+
if (layoutAnimations != null) {
|
|
334
|
+
layoutAnimations.clearAnimationConfigForTag(tag);
|
|
335
|
+
}
|
|
323
336
|
}
|
|
324
337
|
});
|
|
325
338
|
}
|