9
9
10
10
package com.facebook.react.uimanager.layoutanimation
11
11
12
- import android.util.SparseArray
13
12
import android.view.View
14
- import android.view.ViewGroup
15
- import android.view.animation.Animation
16
- import android.view.animation.Animation.AnimationListener
17
13
import com.facebook.react.bridge.Callback
18
14
import com.facebook.react.bridge.ReadableMap
19
- import com.facebook.react.bridge.UiThreadUtil.assertOnUiThread
20
- import com.facebook.react.bridge.UiThreadUtil.getUiThreadHandler
21
15
import com.facebook.react.common.annotations.internal.LegacyArchitecture
22
16
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogLevel
23
- import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger.assertLegacyArchitecture
24
- import com.facebook.react.uimanager.layoutanimation.LayoutAnimationType.Companion.toString
17
+ import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger
25
18
import javax.annotation.concurrent.NotThreadSafe
26
19
27
20
/* *
@@ -36,75 +29,27 @@ import javax.annotation.concurrent.NotThreadSafe
36
29
level = DeprecationLevel .WARNING ,
37
30
)
38
31
public open class LayoutAnimationController {
39
- private val layoutCreateAnimation: AbstractLayoutAnimation = LayoutCreateAnimation ()
40
- private val layoutUpdateAnimation: AbstractLayoutAnimation = LayoutUpdateAnimation ()
41
- private val layoutDeleteAnimation: AbstractLayoutAnimation = LayoutDeleteAnimation ()
42
- private val layoutHandlers = SparseArray <LayoutHandlingAnimation ?>(0 )
43
-
44
- private var shouldAnimateLayout = false
45
- private var maxAnimationDuration: Long = - 1
46
- private var completionRunnable: Runnable ? = null
47
32
48
33
public fun initializeFromConfig (config : ReadableMap ? , completionCallback : Callback ? ) {
49
- if (config == null ) {
50
- reset()
51
- return
52
- }
53
-
54
- shouldAnimateLayout = false
55
- val globalDuration = if (config.hasKey(" duration" )) config.getInt(" duration" ) else 0
56
- if (config.hasKey(toString(LayoutAnimationType .CREATE ))) {
57
- layoutCreateAnimation.initializeFromConfig(
58
- config.getMap(toString(LayoutAnimationType .CREATE ))!! ,
59
- globalDuration,
60
- )
61
- shouldAnimateLayout = true
62
- }
63
- if (config.hasKey(toString(LayoutAnimationType .UPDATE ))) {
64
- layoutUpdateAnimation.initializeFromConfig(
65
- config.getMap(toString(LayoutAnimationType .UPDATE ))!! ,
66
- globalDuration,
67
- )
68
- shouldAnimateLayout = true
69
- }
70
- if (config.hasKey(toString(LayoutAnimationType .DELETE ))) {
71
- layoutDeleteAnimation.initializeFromConfig(
72
- config.getMap(toString(LayoutAnimationType .DELETE ))!! ,
73
- globalDuration,
74
- )
75
- shouldAnimateLayout = true
76
- }
77
-
78
- if (shouldAnimateLayout && completionCallback != null ) {
79
- completionRunnable = Runnable { completionCallback.invoke(java.lang.Boolean .TRUE ) }
80
- }
34
+ LegacyArchitectureLogger .assertLegacyArchitecture(
35
+ " LayoutAnimationController" ,
36
+ LegacyArchitectureLogLevel .ERROR ,
37
+ )
81
38
}
82
39
83
40
public open fun reset () {
84
- layoutCreateAnimation.reset()
85
- layoutUpdateAnimation.reset()
86
- layoutDeleteAnimation.reset()
87
- completionRunnable = null
88
- shouldAnimateLayout = false
89
- maxAnimationDuration = - 1
90
- for (i in layoutHandlers.size() - 1 downTo 0 ) {
91
- val animation = layoutHandlers.valueAt(i)
92
- if (! animation!! .isValid()) {
93
- layoutHandlers.removeAt(i)
94
- }
95
- }
41
+ LegacyArchitectureLogger .assertLegacyArchitecture(
42
+ " LayoutAnimationController" ,
43
+ LegacyArchitectureLogLevel .ERROR ,
44
+ )
96
45
}
97
46
98
47
public open fun shouldAnimateLayout (viewToAnimate : View ? ): Boolean {
99
- // if view parent is null, skip animation: view have been clipped, we don't want animation to
100
- // resume when view is re-attached to parent, which is the standard android animation behavior.
101
- // If there's a layout handling animation going on, it should be animated nonetheless since the
102
- // ongoing animation needs to be updated.
103
- if (viewToAnimate == null ) {
104
- return false
105
- }
106
- return ((shouldAnimateLayout && viewToAnimate.parent != null ) ||
107
- layoutHandlers[viewToAnimate.id] != null )
48
+ LegacyArchitectureLogger .assertLegacyArchitecture(
49
+ " LayoutAnimationController" ,
50
+ LegacyArchitectureLogLevel .ERROR ,
51
+ )
52
+ return false
108
53
}
109
54
110
55
/* *
@@ -119,57 +64,10 @@ public open class LayoutAnimationController {
119
64
* @param height the new height value for the view
120
65
*/
121
66
public open fun applyLayoutUpdate (view : View , x : Int , y : Int , width : Int , height : Int ) {
122
- assertOnUiThread()
123
-
124
- val reactTag = view.id
125
-
126
- // Update an ongoing animation if possible, otherwise the layout update would be ignored as
127
- // the existing animation would still animate to the old layout.
128
- val existingAnimation = layoutHandlers[reactTag]
129
- if (existingAnimation != null ) {
130
- if (! existingAnimation.isValid()) {
131
- layoutHandlers.remove(reactTag)
132
- } else {
133
- existingAnimation.onLayoutUpdate(x, y, width, height)
134
- return
135
- }
136
- }
137
-
138
- // Determine which animation to use : if view is initially invisible, use create animation,
139
- // otherwise use update animation. This approach is easier than maintaining a list of tags
140
- // for recently created views.
141
- val layoutAnimation =
142
- if ((view.width == 0 || view.height == 0 )) layoutCreateAnimation else layoutUpdateAnimation
143
-
144
- val animation = layoutAnimation.createAnimation(view, x, y, width, height)
145
-
146
- if (animation is LayoutHandlingAnimation ) {
147
- animation.setAnimationListener(
148
- object : AnimationListener {
149
- override fun onAnimationStart (animation : Animation ) {
150
- layoutHandlers.put(reactTag, animation as LayoutHandlingAnimation )
151
- }
152
-
153
- override fun onAnimationEnd (animation : Animation ) {
154
- layoutHandlers.remove(reactTag)
155
- }
156
-
157
- override fun onAnimationRepeat (animation : Animation ) = Unit
158
- }
159
- )
160
- } else {
161
- view.layout(x, y, x + width, y + height)
162
- }
163
-
164
- if (animation != null ) {
165
- val animationDuration = animation.duration
166
- if (animationDuration > maxAnimationDuration) {
167
- maxAnimationDuration = animationDuration
168
- scheduleCompletionCallback(animationDuration)
169
- }
170
-
171
- view.startAnimation(animation)
172
- }
67
+ LegacyArchitectureLogger .assertLegacyArchitecture(
68
+ " LayoutAnimationController" ,
69
+ LegacyArchitectureLogLevel .ERROR ,
70
+ )
173
71
}
174
72
175
73
/* *
@@ -181,59 +79,9 @@ public open class LayoutAnimationController {
181
79
* view.
182
80
*/
183
81
public open fun deleteView (view : View , listener : LayoutAnimationListener ) {
184
- assertOnUiThread()
185
-
186
- val animation =
187
- layoutDeleteAnimation.createAnimation(view, view.left, view.top, view.width, view.height)
188
-
189
- if (animation != null ) {
190
- disableUserInteractions(view)
191
-
192
- animation.setAnimationListener(
193
- object : AnimationListener {
194
- override fun onAnimationStart (anim : Animation ) = Unit
195
-
196
- override fun onAnimationRepeat (anim : Animation ) = Unit
197
-
198
- override fun onAnimationEnd (anim : Animation ) {
199
- listener.onAnimationEnd()
200
- }
201
- }
202
- )
203
-
204
- val animationDuration = animation.duration
205
- if (animationDuration > maxAnimationDuration) {
206
- scheduleCompletionCallback(animationDuration)
207
- maxAnimationDuration = animationDuration
208
- }
209
-
210
- view.startAnimation(animation)
211
- } else {
212
- listener.onAnimationEnd()
213
- }
214
- }
215
-
216
- /* * Disables user interactions for a view and all it's subviews. */
217
- private fun disableUserInteractions (view : View ) {
218
- view.isClickable = false
219
- if (view is ViewGroup ) {
220
- for (i in 0 until view.childCount) {
221
- disableUserInteractions(view.getChildAt(i))
222
- }
223
- }
224
- }
225
-
226
- private fun scheduleCompletionCallback (delayMillis : Long ) {
227
- if (completionRunnable != null ) {
228
- val completionHandler = getUiThreadHandler()
229
- completionHandler.removeCallbacks(completionRunnable!! )
230
- completionHandler.postDelayed(completionRunnable!! , delayMillis)
231
- }
232
- }
233
-
234
- private companion object {
235
- init {
236
- assertLegacyArchitecture(" LayoutAnimationController" , LegacyArchitectureLogLevel .ERROR )
237
- }
82
+ LegacyArchitectureLogger .assertLegacyArchitecture(
83
+ " LayoutAnimationController" ,
84
+ LegacyArchitectureLogLevel .ERROR ,
85
+ )
238
86
}
239
87
}
0 commit comments