繼續(xù)記錄DialogFragment使用的坑虏束,當(dāng)然這也算是ViewPager的坑.唆鸡。
需求是這樣的涝影,底部彈框中有N個(gè)頁面。每個(gè)頁面都有一個(gè)列表争占。那么我就用BottomSheetDialogFragment作為底部的彈框。N個(gè)頁面呢序目。我就直接用了一個(gè)viewpager臂痕,然后放N個(gè)fragment進(jìn)去。結(jié)果一開始列表數(shù)據(jù)很少猿涨。不用上下滑動(dòng)握童。所以就沒問題。但是在數(shù)據(jù)多了的時(shí)候叛赚。我發(fā)現(xiàn)只能viewpager可以左右切換正常澡绩。但是其中的列表無法上下滑動(dòng)稽揭,只能滑動(dòng)默認(rèn)加載的第一頁。
來肥卡。分析一下為何只能滑動(dòng)第一頁的recyclerView呢溪掀?
這就要從BottomSheetBehavior源碼說起,關(guān)鍵點(diǎn)在于findScrollingChild方法和事件onInterceptTouchEvent
其他頁面既然滑不動(dòng)步鉴,那么肯定得從事件分發(fā)攔截說起揪胃,我們就直接去onInterceptTouchEvent方法中看最后肯定是被BottomSheetBehavior攔截掉了。
斷點(diǎn)進(jìn)去發(fā)現(xiàn)了其他頁面這個(gè)return最終要滿足這么多條件才被攔截(ACTION_MOVE外的事件條件都是false)氛琢,只有在ACTION_MOVE的時(shí)候喊递,關(guān)鍵點(diǎn)在第二個(gè)斷點(diǎn)parent.isPointInChildBounds(scroll, (int) event.getX(), (int) event.getY()),?它在其他頁面始終返回false阳似,在第一次加載的頁面時(shí)這里返回的是true骚勘。這里的意思是,判斷scroll是否在CoordinatorLayout坐標(biāo)系中撮奏,第一次加載的頁面在其中俏讹。而其他頁面都不再其中。也就被攔截掉了挽荡。導(dǎo)致了recyclerview無法滑動(dòng)藐石。
那么為何只有第一次加載的頁面才在其中呢?看findScrollingChild定拟。
這里的scrollingChild其實(shí)是viewPager
findScrollingChild會(huì)遞歸找R.layout.design_bottom_sheet_dialog中的子view于微,最終找到viewPager中的第一個(gè)recyclerView不為空就設(shè)置了nestedScrollingChildRef =new WeakReference<>(findScrollingChild(child));
nestedScrollingChildRef 就只有一個(gè),所以就是第一次拿到的那個(gè)recyclerView青自,也就是那一個(gè)列表可以滑動(dòng)株依。
那么問題已經(jīng)找到了。怎么解決了延窜。
提供幾種思路恋腕。。還沒驗(yàn)證的哈逆瑞。
1.重寫攔截事件荠藤,只針對(duì)這個(gè)業(yè)務(wù)模式強(qiáng)行return false。
2.nestedScrollingChildRef用list保存获高,findScrollingChild時(shí)保存全部recyclerview哈肖。但這種對(duì)內(nèi)存消耗較大。
推薦使用ViewPager2念秧、一勞永逸淤井。
最后頁面切換如絲般順滑