@@ -38,10 +38,13 @@ internal class ViewTransitionSnapshotManager(
3838) : UIManagerListener {
3939
4040 companion object {
41- private fun captureSoftwareBitmap (view : View ): Bitmap {
42- val bitmap = createBitmap(view.width, view.height)
43- view.draw(Canvas (bitmap))
44- return bitmap
41+ private fun captureSoftwareBitmap (view : View ): Bitmap ? {
42+ if (view.width > 0 && view.height > 0 ) {
43+ val bitmap = createBitmap(view.width, view.height)
44+ view.draw(Canvas (bitmap))
45+ return bitmap
46+ }
47+ return null
4548 }
4649 }
4750
@@ -96,7 +99,7 @@ internal class ViewTransitionSnapshotManager(
9699 } else {
97100 // Software fallback runs synchronously, so onBitmapCaptured always
98101 // completes before setViewSnapshot is called.
99- onBitmapCaptured(reactTag, captureSoftwareBitmap(view))
102+ captureSoftwareBitmap(view)?. let { onBitmapCaptured(reactTag, it) }
100103 }
101104 }
102105 }
@@ -106,9 +109,16 @@ internal class ViewTransitionSnapshotManager(
106109 val location = IntArray (2 )
107110 view.getLocationInWindow(location)
108111
112+ val viewWidth = view.width
113+ val viewHeight = view.height
114+
115+ if (viewWidth <= 0 || viewHeight <= 0 ) {
116+ // Nothing to capture.
117+ return
118+ }
119+
109120 // The view's rect in window coordinates.
110- val viewRect =
111- Rect (location[0 ], location[1 ], location[0 ] + view.width, location[1 ] + view.height)
121+ val viewRect = Rect (location[0 ], location[1 ], location[0 ] + viewWidth, location[1 ] + viewHeight)
112122
113123 // Clamp to window bounds — PixelCopy only captures what's visible on the
114124 // window surface. Without clamping, off-screen portions are black/empty
@@ -144,23 +154,24 @@ internal class ViewTransitionSnapshotManager(
144154 if (copyResult == PixelCopy .SUCCESS ) {
145155 // Compose the clamped capture into a full-size bitmap at the
146156 // correct offset so it aligns with the pseudo-element's bounds.
147- val fullBitmap = createBitmap(view.width, view.height )
157+ val fullBitmap = createBitmap(viewWidth, viewHeight )
148158 Canvas (fullBitmap)
149159 .drawBitmap(clampedBitmap, offsetX.toFloat(), offsetY.toFloat(), null )
150160 clampedBitmap.recycle()
151161 onBitmapCaptured(reactTag, fullBitmap)
152162 } else {
163+ // Fall back to software rendering if the view is still valid.
153164 clampedBitmap.recycle()
154- onBitmapCaptured(reactTag, captureSoftwareBitmap(view))
165+ captureSoftwareBitmap(view)?. let { onBitmapCaptured(reactTag, it) }
155166 }
156167 },
157168 mainHandler,
158169 )
159170 } catch (e: IllegalArgumentException ) {
160171 // Window surface may have been destroyed (e.g., device idle/sleep).
161- // Fall back to software rendering.
172+ // Fall back to software rendering if the view is still valid .
162173 clampedBitmap.recycle()
163- onBitmapCaptured(reactTag, captureSoftwareBitmap(view))
174+ captureSoftwareBitmap(view)?. let { onBitmapCaptured(reactTag, it) }
164175 }
165176 }
166177
0 commit comments