From 5ad7228b4e8650d1fa84bf28db8d810dd0b4aebf Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 23 Mar 2020 14:05:11 +0100 Subject: Going down the BottomSheetBehavior rabbit hole... BottomSheetBehavior only supports one scrolling child. Add support for a ViewPager. ViewPager.getChildAt sometimes does not match the actual position. Make sure that it keeps all children using setOffscreenPageLimit --- .../bottomsheet/ViewPagerBottomSheetBehavior.java | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java (limited to 'app/src/main/java/com/google') diff --git a/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java b/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java new file mode 100644 index 000000000..2d211704d --- /dev/null +++ b/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java @@ -0,0 +1,75 @@ +package com.google.android.material.bottomsheet; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.view.ViewCompat; +import androidx.viewpager.widget.ViewPager; + +import java.lang.ref.WeakReference; + +/** + * Override {@link #findScrollingChild(View)} to support {@link ViewPager}'s nested scrolling. + * By the way, In order to override package level method and field. + * This class put in the same package path where {@link BottomSheetBehavior} located. + * Source: https://medium.com/@hanru.yeh/funny-solution-that-makes-bottomsheetdialog-support-viewpager-with-nestedscrollingchilds-bfdca72235c3 + */ +public class ViewPagerBottomSheetBehavior extends BottomSheetBehavior { + + public ViewPagerBottomSheetBehavior() { + super(); + } + + public ViewPagerBottomSheetBehavior(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + View findScrollingChild(View view) { + if (ViewCompat.isNestedScrollingEnabled(view)) { + return view; + } + + if (view instanceof ViewPager) { + ViewPager viewPager = (ViewPager) view; + View currentViewPagerChild = viewPager.getChildAt(viewPager.getCurrentItem()); + return findScrollingChild(currentViewPagerChild); + } else if (view instanceof ViewGroup) { + ViewGroup group = (ViewGroup) view; + for (int i = 0, count = group.getChildCount(); i < count; i++) { + View scrollingChild = findScrollingChild(group.getChildAt(i)); + if (scrollingChild != null) { + return scrollingChild; + } + } + } + return null; + } + + public void updateScrollingChild() { + final View scrollingChild = findScrollingChild(viewRef.get()); + nestedScrollingChildRef = new WeakReference<>(scrollingChild); + } + + /** + * A utility function to get the {@link ViewPagerBottomSheetBehavior} associated with the {@code view}. + * + * @param view The {@link View} with {@link ViewPagerBottomSheetBehavior}. + * @return The {@link ViewPagerBottomSheetBehavior} associated with the {@code view}. + */ + @SuppressWarnings("unchecked") + public static ViewPagerBottomSheetBehavior from(V view) { + ViewGroup.LayoutParams params = view.getLayoutParams(); + if (!(params instanceof CoordinatorLayout.LayoutParams)) { + throw new IllegalArgumentException("The view is not a child of CoordinatorLayout"); + } + CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) params).getBehavior(); + if (!(behavior instanceof ViewPagerBottomSheetBehavior)) { + throw new IllegalArgumentException( + "The view is not associated with ViewPagerBottomSheetBehavior"); + } + return (ViewPagerBottomSheetBehavior) behavior; + } +} \ No newline at end of file -- cgit v1.2.3