I got troubles and I think it is CoordinatorLayout
's fault but not sure. I'm using ViewPager2
inside a ConstraintLayout
and I use the CoordinatorLayout
like BottomSheet
. But when I drag to hide it not works good. I replaced the ViewPager2
by ViewPager
and it works well. I hope you can help me.
This is my XML file:
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/bottom_sheet_behavior"
app:behavior_hideable="false"
app:behavior_peekHeight="60dp" >
<androidx.viewpager2.widget.ViewPager2
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="4:3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="#0000FF"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
This can be solved by disabling the nested scrolling of the ViewPager2
RecyclerView
; but since the RecyclerView
can't be directly accessed through the ViewPager2
library. Then it can't be achieved in layout.
So, instead we can get that RecyclerView
using java reflection as follows:
Java:
public static RecyclerView getRecyclerView(ViewPager2 viewPager) {
try {
Field field = ViewPager2.class.getDeclaredField("mRecyclerView");
field.setAccessible(true);
return (RecyclerView) field.get(viewPager);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
Kotlin:
fun ViewPager2.getRecyclerView(): RecyclerView? {
try {
val field = ViewPager2::class.java.getDeclaredField("mRecyclerView")
field.isAccessible = true
return field.get(this) as RecyclerView
} catch (e: NoSuchFieldException) {
e.printStackTrace()
} catch (e: IllegalAccessException) {
e.printStackTrace()
}
return null
}
Then disable the nested scrolling:
Java:
RecyclerView recyclerView = getRecyclerView(viewPager);
if (recyclerView != null) {
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER); // Optional
}
Kotlin:
val recyclerView = viewPager.getRecyclerView()
recyclerView?.isNestedScrollingEnabled = false
recyclerView?.overScrollMode = View.OVER_SCROLL_NEVER // Optional
This works with me without setting the OverScrollMode
, so, if it doesn't work with you can disable the OverScrollMode
like above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With