프로그래밍/Android

[안드로이드] java.lang.IllegalStateException: An instance of OnFlingListener already set 해결

Lou Park 2023. 1. 26. 23:24

문제 발생

@ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT)
internal class PagerSnapHelperCarousel @JvmOverloads constructor(
context: Context
) : Carousel(context) {
init {
if (onFlingListener == null) {
PagerSnapHelper().attachToRecyclerView(this)
}
}
}

Epoxy의 Custom Carousel로 SnapHelper를 붙이는 도중 OnFlingListener가 이미 등록되어있다는 오류가 발생했다. 당연하게도 이유는 RecyclerVIewOnFlingListener가 이미 등록되어 있어서다.

java.lang.IllegalStateException: An instance of OnFlingListener already set.
at androidx.recyclerview.widget.SnapHelper.setupCallbacks(SnapHelper.java:113)
at androidx.recyclerview.widget.SnapHelper.attachToRecyclerView(SnapHelper.java:101)
at com.xxxx.PagerSnapHelperCarousel.<init>(PagerSnapHelperCarousel.kt:13)
at com.xxxx.PagerSnapHelperCarouselModel_.buildView(PagerSnapHelperCarouselModel_.java:97)
at com.xxxx.PagerSnapHelperCarouselModel_.buildView(PagerSnapHelperCarouselModel_.java:32)
at com.airbnb.epoxy.BaseEpoxyAdapter.onCreateViewHolder(BaseEpoxyAdapter.java:100)
at com.airbnb.epoxy.BaseEpoxyAdapter.onCreateViewHolder(BaseEpoxyAdapter.java:20)
at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:7719)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6804)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6688)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6684)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2349)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1649)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1609)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:686)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4604)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:4307)
at androidx.recyclerview.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:2065)
at androidx.recyclerview.widget.RecyclerView$1.run(RecyclerView.java:438)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1108)
at android.view.Choreographer.doCallbacks(Choreographer.java:866)
at android.view.Choreographer.doFrame(Choreographer.java:792)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1092)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8751)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

 

해결 방법

현재 RecyclerViewonFlingListenernull인지 체크 후, null일때만 SnapHelper를 등록해주면된다. 혹은 직접 없애버려도 될 것이다.

if (onFlingListener == null) {
PagerSnapHelper().attachToRecyclerView(this) // this = recyclerview
}

 

이유는?

attachToRecyclerView()에서 OnFlightListener를 등록하고 있고, 정확히 해당 에러를 뱉는 부분에서 동일한 검사를 시행하고 있기때문이다.

public void attachToRecyclerView(@Nullable RecyclerView recyclerView)
throws IllegalStateException {
// ...
if (mRecyclerView != null) {
setupCallbacks();
// ...
}
}
/**
* 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.setOnFlingListener(this);
}