react-native-morph-card 0.1.0 → 0.1.2
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.
|
@@ -14,6 +14,7 @@ import android.util.Log
|
|
|
14
14
|
import android.view.View
|
|
15
15
|
import android.view.ViewGroup
|
|
16
16
|
import android.view.ViewOutlineProvider
|
|
17
|
+
import android.view.ViewTreeObserver
|
|
17
18
|
import android.view.animation.PathInterpolator
|
|
18
19
|
import android.widget.FrameLayout
|
|
19
20
|
import android.widget.ImageView
|
|
@@ -54,6 +55,7 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
|
|
|
54
55
|
private var targetScreenContainerRef: WeakReference<View>? = null
|
|
55
56
|
private var screenStackRef: WeakReference<ViewGroup>? = null
|
|
56
57
|
private var hierarchyListener: ViewGroup.OnHierarchyChangeListener? = null
|
|
58
|
+
private var preDrawListener: ViewTreeObserver.OnPreDrawListener? = null
|
|
57
59
|
|
|
58
60
|
// Spring-like interpolator (approximates iOS dampingRatio:0.85)
|
|
59
61
|
private val springInterpolator = PathInterpolator(0.25f, 1.0f, 0.5f, 1.0f)
|
|
@@ -222,10 +224,59 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
|
|
|
222
224
|
}
|
|
223
225
|
}
|
|
224
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Walk the view tree and hide any screen container that isn't already known.
|
|
229
|
+
* This catches modal screens added to separate ScreenStacks (e.g. transparentModal).
|
|
230
|
+
*/
|
|
231
|
+
private fun hideNewScreenContainers(root: ViewGroup, knownScreens: Set<View>) {
|
|
232
|
+
fun walk(group: ViewGroup) {
|
|
233
|
+
val name = group.javaClass.name
|
|
234
|
+
if (name.contains("ScreenStack") || name.contains("ScreenContainer")) {
|
|
235
|
+
for (i in 0 until group.childCount) {
|
|
236
|
+
val child = group.getChildAt(i)
|
|
237
|
+
if (!knownScreens.contains(child) && child.visibility == View.VISIBLE) {
|
|
238
|
+
child.visibility = View.INVISIBLE
|
|
239
|
+
Log.d(TAG, "preDraw: hid new screen ${child.javaClass.simpleName} in ${group.javaClass.simpleName}")
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
for (i in 0 until group.childCount) {
|
|
244
|
+
val child = group.getChildAt(i)
|
|
245
|
+
if (child is ViewGroup) walk(child)
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
walk(root)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Collect all current children of ScreenStack/ScreenContainer views.
|
|
253
|
+
*/
|
|
254
|
+
private fun collectExistingScreens(root: ViewGroup): Set<View> {
|
|
255
|
+
val screens = mutableSetOf<View>()
|
|
256
|
+
fun walk(group: ViewGroup) {
|
|
257
|
+
val name = group.javaClass.name
|
|
258
|
+
if (name.contains("ScreenStack") || name.contains("ScreenContainer")) {
|
|
259
|
+
for (i in 0 until group.childCount) {
|
|
260
|
+
screens.add(group.getChildAt(i))
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
for (i in 0 until group.childCount) {
|
|
264
|
+
val child = group.getChildAt(i)
|
|
265
|
+
if (child is ViewGroup) walk(child)
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
walk(root)
|
|
269
|
+
return screens
|
|
270
|
+
}
|
|
271
|
+
|
|
225
272
|
private fun removeHierarchyListener() {
|
|
226
273
|
screenStackRef?.get()?.setOnHierarchyChangeListener(null)
|
|
227
274
|
screenStackRef = null
|
|
228
275
|
hierarchyListener = null
|
|
276
|
+
preDrawListener?.let { listener ->
|
|
277
|
+
getDecorView()?.viewTreeObserver?.removeOnPreDrawListener(listener)
|
|
278
|
+
preDrawListener = null
|
|
279
|
+
}
|
|
229
280
|
}
|
|
230
281
|
|
|
231
282
|
// ══════════════════════════════════════════════════════════════
|
|
@@ -286,7 +337,7 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
|
|
|
286
337
|
override fun onChildViewAdded(parent: View?, child: View?) {
|
|
287
338
|
if (child != null && child !== sourceScreen) {
|
|
288
339
|
child.visibility = View.INVISIBLE
|
|
289
|
-
Log.d(TAG, "prepareExpand: intercepted new screen, set INVISIBLE")
|
|
340
|
+
Log.d(TAG, "prepareExpand: hierarchy intercepted new screen, set INVISIBLE")
|
|
290
341
|
}
|
|
291
342
|
}
|
|
292
343
|
override fun onChildViewRemoved(parent: View?, child: View?) {}
|
|
@@ -296,6 +347,18 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
|
|
|
296
347
|
hierarchyListener = listener
|
|
297
348
|
}
|
|
298
349
|
|
|
350
|
+
// Also install a pre-draw listener on the DecorView to catch modal screens
|
|
351
|
+
// that are added to a different ScreenStack (e.g. transparentModal).
|
|
352
|
+
// This fires before every frame draw, so we can hide screens before they render.
|
|
353
|
+
val knownScreens = collectExistingScreens(decorView)
|
|
354
|
+
Log.d(TAG, "prepareExpand: tracking ${knownScreens.size} existing screens")
|
|
355
|
+
val pdListener = ViewTreeObserver.OnPreDrawListener {
|
|
356
|
+
hideNewScreenContainers(decorView, knownScreens)
|
|
357
|
+
true
|
|
358
|
+
}
|
|
359
|
+
decorView.viewTreeObserver.addOnPreDrawListener(pdListener)
|
|
360
|
+
preDrawListener = pdListener
|
|
361
|
+
|
|
299
362
|
// Capture snapshot
|
|
300
363
|
val cardImage = captureSnapshot()
|
|
301
364
|
|
package/package.json
CHANGED