Android --- RecyclerViwe中使用SnapHelper报错:“An instance of OnFlingListener already set.”
文章目錄
- 1.SnapHelper 的應用情景
- 2.問題現象
- 3.分析原因
- 4.原因重點:(SnapHelper被多次創(chuàng)建并綁定到同一個RecyclerView)
- 5.解決方法
- 5.1第一種方法:
- 5.2第二種方法:
- 6原理剖析
- 7源碼解析:
1.SnapHelper 的應用情景
通常我們使用RecyclerView來實現簡單圖片輪播圖Banner時,需要實現按圖片翻頁效果,但RecyclerView會在滾動過程中是“過程停留”無法達到“翻頁”效果,這時候我們就不得不借助SnapHelper類來使得RecyclerView具備類似ViewPager“翻頁”效果的能力。但隨著頁面UI布局的復雜性,有時候我們需要嵌套RecyclerView并結合SnapHelper。
2.問題現象
多層RecyclerView嵌套時使用SnapHelper工具類配合,向下滾動Item列表正常,但向上滾動會立即強退并殺死app程序。報錯問題:“java.lang.IllegalStateException: An instance of OnFlingListener already set.”
3.分析原因
首先來了解一個概念,手指在屏幕上滑動RecyclerView然后松手,RecyclerView中的內容會順著慣性繼續(xù)往手指滑動的方向繼續(xù)滾動直到停止,這個過程叫做Fling。Fling操作從手指離開屏幕瞬間被觸發(fā),在滾動停止時結束。而OnFlingListener顯然就是監(jiān)聽Fling滾動事件的監(jiān)聽器。
4.原因重點:(SnapHelper被多次創(chuàng)建并綁定到同一個RecyclerView)
通常我們在做RecyclerView的嵌套時總會遇到這樣的問題,是因為每次在onBindViewHolder中都這樣寫:
SnapHelper snapHelper = new PagerSnapHelper() snapHelper.attachToRecyclerView(recyclerView)每次滑動RecyclerView都需要重新創(chuàng)建SnapHelper對象并將其附著到RecyclerView上,導致一個RecyclerIView會綁定多個SnapHelper,在回頭繪制RecyclerView時,會發(fā)現一個RecyclerView的SnapHelper實例(多個)重復設置,導致滾動事件出問題而退出滾動,致使整個app應用崩潰退出!
5.解決方法
5.1第一種方法:
在重新繪制RecyclerView時首先移除創(chuàng)建的前一個SnapHelper實例的OnFlingListener監(jiān)聽器。
Tips:也就是RecyclerView在第二次滑動到該位置時
Java語言
SnapHelper snapHelper = new PagerSnapHelper()recycleView.setOnFlingListener(null)snapHelper.attachToRecyclerView(recyclerView)Kotlin語言
val snapHelper: SnapHelper = PagerSnapHelper() recycleView.onFlingListener = null snapHelper.attachToRecyclerView(recyclerView)Tips:SnapHelper通過attachToRecyclerView()方法附著到RecyclerView上,從而實現輔助RecyclerView滾動對齊操作。
5.2第二種方法:
將SnapHelper snapHelper = new
PagerSnapHelper()放在全局定義(針對類),允許類中只存在一個SnapHelper對象。每次重新繪制RecyclerView時總是調用該SnapHelper實例對象的onFlingListener。
Tips:此方法不用添加任何代碼,僅需要將SnapHelper snapHelper = new
PagerSnapHelper()放在與重寫方法onBindViewHolder()同級的位置。
6原理剖析
據下面的源碼可以看到當與RecyclerView綁定的SnapHelper實例對象的OnFlingListener已經被設置時,再次設置系統(tǒng)會拋出異常:”An instance of OnFlingListener already set.“
7源碼解析:
錯誤類型&具體錯誤:IllegalArgumentException:An instance of OnFlingListener already set. /*** Attaches the {@link SnapHelper} to the provided RecyclerView, by calling* {@link RecyclerView#setOnFlingListener(RecyclerView.OnFlingListener)}.* You can call this method with {@code null} to detach it from the current RecyclerView.** @param recyclerView The RecyclerView instance to which you want to add this helper or* {@code null} if you want to remove SnapHelper from the current* RecyclerView.** @throws IllegalArgumentException if there is already a {@link RecyclerView.OnFlingListener}* attached to the provided {@link RecyclerView}.**/ /*** Called when an instance of a {@link RecyclerView} is attached.*/private void setupCallbacks() throws IllegalStateException {if (mRecyclerView.getOnFlingListener() != null) {throw new IllegalStateException("An instance of OnFlingListener already set.");}mRecyclerView.addOnScrollListener(mScrollListener);mRecyclerView.setOnFlingListener(this);}總結
以上是生活随笔為你收集整理的Android --- RecyclerViwe中使用SnapHelper报错:“An instance of OnFlingListener already set.”的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android --- 调用MediaS
- 下一篇: Android——推荐一款好用的倒计时控