material-components / material-components-android

Modular and customizable Material Design UI components for Android
Apache License 2.0
16.28k stars 3.06k forks source link

BottomSheetBehavior.findScrollingChild error with viewpager #373

Open zhuantou233 opened 5 years ago

zhuantou233 commented 5 years ago

We're transitioning from github issues to a public buganizer component. Rather than submitting a bug here on github, please file any bugs or feature requests at https://issuetracker.google.com/issues/new?component=439535.

error link

Because of BottomSheetBehavior.findScrollingChild, if I use BottomSheetDialog with ViewPager, the second or more Fragment can't scroll.

The solution in the link will create new behavior not extend BottomSheetBehavior, which is not so elegant and will add new dialog or dialogfragment.

Hope it will be solved.

melaniegoetz commented 5 years ago

Hi! Could you please provide your code and more explanation as to your desired result?

zhuantou233 commented 5 years ago

Hi! Could you please provide your code and more explanation as to your desired result?

https://github.com/choongyouqi/bottomsheet and the error gif is in the error link: https://stackoverflow.com/questions/39326321/scroll-not-working-for-multiple-recyclerview-in-bottomsheet?noredirect=1&lq=1

Actual result: When using BottomSheetDialog and ViewPager with 2 more fragment, and each fragment contains RecyclerView, only one fragment recyclerview can scroll while the other can't scroll. This error comes from BottomSheetBehavior.findScrollingChild

private View findScrollingChild(View view) {
    if (view instanceof NestedScrollingChild) {
        return view;
    }
    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;
}

Expected result: We want each RecyclerView fragment could scroll normally without define a new BottomSheetBehavior

MuntashirAkon commented 2 years ago

Any updates on this? The linked SO question is over six years old!

yfcyfc123234 commented 4 months ago
  sheetDataBinding.viewPager.apply {
addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
                override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}

                override fun onPageSelected(position: Int) {
                    fragments.forEachIndexed { index, fragment ->
                        fragment.handleNestedScrollingEnabled(position == index)
                    }
                }

                override fun onPageScrollStateChanged(state: Int) {}
            })

             fun handleNestedScrollingEnabled(isNestedScrollingEnabled: Boolean) {
        runCatching {
            if (isAdded) {
                dataBinding.rv.isNestedScrollingEnabled = isNestedScrollingEnabled
            }
        }.onFailure {
            logE(it)
        }
}
    }

    class TestCoordinatorLayout @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : CoordinatorLayout(context, attrs) {
    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean = super.onInterceptTouchEvent(ev).also { showOnInterceptTouchEvent(it, ev) }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(ev: MotionEvent?): Boolean = super.onTouchEvent(ev).also { showOnTouchEvent(it, ev) }

    private val out = Rect()
    override fun isPointInChildBounds(child: View, x: Int, y: Int): Boolean {
        if (child is RecyclerView) {
            ViewGroupUtils.getDescendantRect(this, child, out)

            if (out.left != 0) {
                out.offset(-out.left, 0)
            }

            val contains = out.contains(x, y)
            logE("out=${out} ${x} ${y} $contains")
            return contains
        }

        return super.isPointInChildBounds(child, x, y)
    }
}