From 7d87ed44bb77855f5b7d82bf60bdd459ac339387 Mon Sep 17 00:00:00 2001 From: Joni Van Roost Date: Thu, 13 Feb 2025 17:45:13 +0100 Subject: [PATCH] fix: pager view recycling crash --- .../PagerViewViewManagerImpl.kt | 54 +++++++++++++++---- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/android/src/main/java/com/reactnativepagerview/PagerViewViewManagerImpl.kt b/android/src/main/java/com/reactnativepagerview/PagerViewViewManagerImpl.kt index ad7ea468..a75927fb 100644 --- a/android/src/main/java/com/reactnativepagerview/PagerViewViewManagerImpl.kt +++ b/android/src/main/java/com/reactnativepagerview/PagerViewViewManagerImpl.kt @@ -63,22 +63,36 @@ object PagerViewViewManagerImpl { fun removeAllViews(parent: NestedScrollableHost) { val pager = getViewPager(parent) pager.isUserInputEnabled = false + + // Get the RecyclerView inside ViewPager2 + val recyclerView = pager.getChildAt(0) as? androidx.recyclerview.widget.RecyclerView + + // Clear any pending animations/operations + recyclerView?.suppressLayout(true) + val adapter = pager.adapter as ViewPagerAdapter? adapter?.removeAll() + + // Re-enable layout after cleanup + recyclerView?.suppressLayout(false) } fun removeViewAt(parent: NestedScrollableHost, index: Int) { val pager = getViewPager(parent) - val adapter = pager.adapter as ViewPagerAdapter? + pager.isUserInputEnabled = false - val child = adapter?.getChildAt(index) + // Get the RecyclerView inside ViewPager2 + val recyclerView = pager.getChildAt(0) as? androidx.recyclerview.widget.RecyclerView - if (child != null && child.parent != null) { - (child.parent as? ViewGroup)?.removeView(child) - } + // Clear any pending animations/operations + recyclerView?.suppressLayout(true) + val adapter = pager.adapter as ViewPagerAdapter? adapter?.removeChildAt(index) + // Re-enable layout after cleanup + recyclerView?.suppressLayout(false) + refreshViewChildrenLayout(pager) } @@ -156,10 +170,30 @@ object PagerViewViewManagerImpl { private fun refreshViewChildrenLayout(view: View) { view.post { - view.measure( - View.MeasureSpec.makeMeasureSpec(view.width, View.MeasureSpec.EXACTLY), - View.MeasureSpec.makeMeasureSpec(view.height, View.MeasureSpec.EXACTLY)) - view.layout(view.left, view.top, view.right, view.bottom) + try { + if (view is ViewPager2) { + // Get the RecyclerView inside ViewPager2 + val recyclerView = view.getChildAt(0) as? androidx.recyclerview.widget.RecyclerView + + // Temporarily suppress layout operations + recyclerView?.suppressLayout(true) + + view.measure( + View.MeasureSpec.makeMeasureSpec(view.width, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(view.height, View.MeasureSpec.EXACTLY)) + view.layout(view.left, view.top, view.right, view.bottom) + + // Re-enable layout operations + recyclerView?.suppressLayout(false) + } else { + view.measure( + View.MeasureSpec.makeMeasureSpec(view.width, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(view.height, View.MeasureSpec.EXACTLY)) + view.layout(view.left, view.top, view.right, view.bottom) + } + } catch (e: Exception) { + // Ignore layout errors during cleanup + } } } -} \ No newline at end of file +}