fix android pager recycling crash
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
diff --git a/android/src/main/java/com/swmansion/rnscreens/Screen.kt b/android/src/main/java/com/swmansion/rnscreens/Screen.kt
|
||||
index c99ca362df5baee81fa48d1c9ef09b40a2c23f07..725c07aa0ed516f9dd09f81e522f2d3191d9b5d0 100644
|
||||
--- a/android/src/main/java/com/swmansion/rnscreens/Screen.kt
|
||||
+++ b/android/src/main/java/com/swmansion/rnscreens/Screen.kt
|
||||
@@ -17,6 +17,7 @@ import androidx.annotation.RequiresApi
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.children
|
||||
import androidx.fragment.app.Fragment
|
||||
+import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.facebook.react.bridge.GuardedRunnable
|
||||
import com.facebook.react.bridge.ReactContext
|
||||
@@ -637,7 +638,7 @@ class Screen(
|
||||
endTransitionRecursive(childView.toolbar)
|
||||
}
|
||||
|
||||
- if (childView is ViewGroup) {
|
||||
+ if (childView is ViewGroup && childView !is RecyclerView) {
|
||||
endTransitionRecursive(childView)
|
||||
}
|
||||
}
|
||||
@@ -666,7 +667,10 @@ class Screen(
|
||||
startTransitionRecursive(child.toolbar)
|
||||
}
|
||||
|
||||
- if (child is ViewGroup) {
|
||||
+ // Transition a RecyclerView as one unit. Marking its recyclable children as
|
||||
+ // transitioning keeps their parent set after removal, so RecyclerView crashes
|
||||
+ // when it tries to recycle them during the screen transition.
|
||||
+ if (child is ViewGroup && child !is RecyclerView) {
|
||||
startTransitionRecursive(child)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
# react-native-screens+4.24.0.patch
|
||||
|
||||
## Android: do not transition RecyclerView children individually
|
||||
|
||||
Fixes `Scrapped or attached views may not be recycled` when leaving a screen while a nested ViewPager2 is still settling.
|
||||
|
||||
When a screen removal starts, react-native-screens recursively calls `startViewTransition()` on every descendant. Android intentionally keeps a transitioning view's `parent` set after it is removed so that the parent can continue drawing it until `endViewTransition()`.
|
||||
|
||||
This violates RecyclerView's requirement that a ViewHolder be fully detached before recycling: if ViewPager2 recycles a page during the screen transition, the holder has been removed from RecyclerView's child array but still reports RecyclerView as its parent.
|
||||
|
||||
The patch transitions a RecyclerView as a single unit without recursively transitioning its recyclable children. The matching end traversal skips the same children.
|
||||
|
||||
Related issues:
|
||||
- https://github.com/callstack/react-native-pager-view/issues/1005
|
||||
- https://github.com/software-mansion/react-native-screens/issues/2461
|
||||
Reference in New Issue
Block a user