DialogFragment+viewPager+fragment+recyclerView

继续记录DialogFragment使用的坑,当然这也算是ViewPager的坑.。

需求是这样的,底部弹框中有N个页面。每个页面都有一个列表。那么我就用BottomSheetDialogFragment作为底部的弹框。N个页面呢。我就直接用了一个viewpager,然后放N个fragment进去。结果一开始列表数据很少。不用上下滑动。所以就没问题。但是在数据多了的时候。我发现只能viewpager可以左右切换正常。但是其中的列表无法上下滑动,只能滑动默认加载的第一页。

来。分析一下为何只能滑动第一页的recyclerView呢?

这就要从BottomSheetBehavior源码说起,关键点在于findScrollingChild方法和事件onInterceptTouchEvent


其他页面既然滑不动,那么肯定得从事件分发拦截说起,我们就直接去onInterceptTouchEvent方法中看最后肯定是被BottomSheetBehavior拦截掉了。


onInterceptTouchEvent

断点进去发现了其他页面这个return最终要满足这么多条件才被拦截(ACTION_MOVE外的事件条件都是false),只有在ACTION_MOVE的时候,关键点在第二个断点parent.isPointInChildBounds(scroll, (int) event.getX(), (int) event.getY()), 它在其他页面始终返回false,在第一次加载的页面时这里返回的是true。这里的意思是,判断scroll是否在CoordinatorLayout坐标系中,第一次加载的页面在其中。而其他页面都不再其中。也就被拦截掉了。导致了recyclerview无法滑动。

那么为何只有第一次加载的页面才在其中呢?看findScrollingChild。


findScrollingChild

这里的scrollingChild其实是viewPager

dialog中xml示例代码

findScrollingChild会递归找R.layout.design_bottom_sheet_dialog中的子view,最终找到viewPager中的第一个recyclerView不为空就设置了nestedScrollingChildRef =new WeakReference<>(findScrollingChild(child));

nestedScrollingChildRef 就只有一个,所以就是第一次拿到的那个recyclerView,也就是那一个列表可以滑动。

那么问题已经找到了。怎么解决了。


提供几种思路。。还没验证的哈。


1.重写拦截事件,只针对这个业务模式强行return false。

2.nestedScrollingChildRef用list保存,findScrollingChild时保存全部recyclerview。但这种对内存消耗较大。

推荐使用ViewPager2、一劳永逸。

最后页面切换如丝般顺滑

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容