Funny Solution that Makes BottomSheetDialog Support ViewPager with NestedScrollingChilds

Recently we have a special feature which need a complicated composition in BottomSheetDialog. That architecture is 1.) create a BottomSheetDialog, 2.) add ViewPager as major content, 3.) each page has its own RecyclerView.

Bram Yeh
2 min readMay 15, 2018

This is easy implementation (at our first opinion) until we found the scrolling behavior on RecyclerView of 2nd page is gone after swiping to the next page. And than, my colleague Samuel investigated and found out this solution.

Update in Jan 5, 2019 from Mo Li

viewPager.getChildAt(viewPager.getCurrentItem()) doesn’t works for me. it may not return the view of current selected page.
My solution:

@VisibleForTesting
override fun findScrollingChild(view: View): View? {
return if (view is ViewPager) {
view.focusedChild?.let { findScrollingChild(it) }
} else {
super.findScrollingChild(view)
}
}

Thanks Mo Li’s comment and improve this solution.

How does BottomSheetDialog support NestedScrollingChild

BottomSheetDialog has a default BottomSheetBehavior, so it can handle nested scrolling view without any extra implementation. It will get reference of nested scrolling view on onLayoutChild(),

public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection) {
....
mNestedScrollingChildRef = new WeakReference<>(findScrollingChild(child));
}

Why scrolling is gone after swiping to another page of ViewPager

As previous introduction, BottomSheetBehavior only get the reference on onLayoutChid(), that means, BottomSheetBehavior doesn’t get callback from ViewPager when changing its current page, so it won’t update the reference.

Here we can refer the source code of BottomSheetBehavior.

How to update reference of the scrolling child of BottomSheetBehavior

Even there are so many solutions in Stack Overflow, our member chosen a different solution to resolve this issue: to extend default BottomSheetBehavior, and then add a public method to update scrolling child reference when ViewPager changes its current item.

ViewPagerBottomSheetBehavior extends BottomSheetBehaviors, and there is a new method, updateScrollingChild(), which calls findScrollingChild() to update the reference. And more, because original findScrollingChild() only support ViewGroup, we need to override original updateScrollingChild() to support ViewPager, from line 24 ~ 30.

And then we set customized bottom-sheet-behavior when creating BottomSheetDialog, and call updateScrollingChild() when onPageSelected()

Because we need to access the package-private variable, mNestedScrollingChildRef, we have to put ViewPagerBottomSheetBehavior inside package android.support.design.widget. That why I call the solution funny.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Bram Yeh
Bram Yeh

Written by Bram Yeh

Lead Android & iOS Mobile Engineer at Yahoo (Verizon Media) Taiwan https://www.linkedin.com/in/hanruyeh/

Responses (9)

Write a response