react-native-morph-card 0.1.0 → 0.1.1
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,53 @@ 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 the source screen.
|
|
229
|
+
* This catches modal screens added to separate ScreenStacks.
|
|
230
|
+
*/
|
|
231
|
+
private fun hideNewScreenContainers(root: ViewGroup, sourceScreen: 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 (child !== sourceScreen && child.visibility == View.VISIBLE) {
|
|
238
|
+
// Check if this is a screen container we haven't seen before
|
|
239
|
+
val childScreen = child
|
|
240
|
+
val isSourceAncestor = isAncestorOf(childScreen, sourceScreen)
|
|
241
|
+
if (!isSourceAncestor) {
|
|
242
|
+
childScreen.visibility = View.INVISIBLE
|
|
243
|
+
Log.d(TAG, "preDraw: hid screen container ${childScreen.javaClass.simpleName}")
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
for (i in 0 until group.childCount) {
|
|
249
|
+
val child = group.getChildAt(i)
|
|
250
|
+
if (child is ViewGroup) walk(child)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
walk(root)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
private fun isAncestorOf(potentialAncestor: View, target: View?): Boolean {
|
|
257
|
+
if (target == null) return false
|
|
258
|
+
var current: View? = target
|
|
259
|
+
while (current != null) {
|
|
260
|
+
if (current === potentialAncestor) return true
|
|
261
|
+
current = if (current.parent is View) current.parent as View else null
|
|
262
|
+
}
|
|
263
|
+
return false
|
|
264
|
+
}
|
|
265
|
+
|
|
225
266
|
private fun removeHierarchyListener() {
|
|
226
267
|
screenStackRef?.get()?.setOnHierarchyChangeListener(null)
|
|
227
268
|
screenStackRef = null
|
|
228
269
|
hierarchyListener = null
|
|
270
|
+
preDrawListener?.let { listener ->
|
|
271
|
+
getDecorView()?.viewTreeObserver?.removeOnPreDrawListener(listener)
|
|
272
|
+
preDrawListener = null
|
|
273
|
+
}
|
|
229
274
|
}
|
|
230
275
|
|
|
231
276
|
// ══════════════════════════════════════════════════════════════
|
|
@@ -286,7 +331,7 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
|
|
|
286
331
|
override fun onChildViewAdded(parent: View?, child: View?) {
|
|
287
332
|
if (child != null && child !== sourceScreen) {
|
|
288
333
|
child.visibility = View.INVISIBLE
|
|
289
|
-
Log.d(TAG, "prepareExpand: intercepted new screen, set INVISIBLE")
|
|
334
|
+
Log.d(TAG, "prepareExpand: hierarchy intercepted new screen, set INVISIBLE")
|
|
290
335
|
}
|
|
291
336
|
}
|
|
292
337
|
override fun onChildViewRemoved(parent: View?, child: View?) {}
|
|
@@ -296,6 +341,17 @@ class MorphCardSourceView(context: Context) : ReactViewGroup(context) {
|
|
|
296
341
|
hierarchyListener = listener
|
|
297
342
|
}
|
|
298
343
|
|
|
344
|
+
// Also install a pre-draw listener on the DecorView to catch modal screens
|
|
345
|
+
// that are added to a different ScreenStack (e.g. transparentModal).
|
|
346
|
+
// This fires before every frame draw, so we can hide screens before they render.
|
|
347
|
+
val savedSourceScreen = sourceScreen
|
|
348
|
+
val pdListener = ViewTreeObserver.OnPreDrawListener {
|
|
349
|
+
hideNewScreenContainers(decorView, savedSourceScreen)
|
|
350
|
+
true
|
|
351
|
+
}
|
|
352
|
+
decorView.viewTreeObserver.addOnPreDrawListener(pdListener)
|
|
353
|
+
preDrawListener = pdListener
|
|
354
|
+
|
|
299
355
|
// Capture snapshot
|
|
300
356
|
val cardImage = captureSnapshot()
|
|
301
357
|
|
package/package.json
CHANGED