I'm using a RecyclerView in my Android app. I've many cardviews in my RecyclerView, such that only 1 cardview is displayed to the user at a time. The user has to swipe to see the next card.
I faced an issue that when user makes a swipe, the recyclerview gets scrolled to the end. Instead, what I need is when the user swipes, display the next card to the user as mentioned in this post.
How to make swipe on horizontal recyclerview bring only the next item into view - Android
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
I tried the answer mentioned in the above link. But I'm getting an exception when the user makes a swipe.
Please help me resolve it.
Error
java.lang.IllegalStateException: An instance of OnFlingListener already set.
at android.support.v7.widget.SnapHelper.setupCallbacks(SnapHelper.java:114)
at android.support.v7.widget.SnapHelper.attachToRecyclerView(SnapHelper.java:102)
at com.abc.ui.trm.TrCard.setupCardView(TrCard.java:62)
at com.abc.ui.trm.TrCard.setupCardView(TrCard.java:29)
at com.abc.ui.core.card.BaseCardView.processCardView(BaseCardView.java:134)
at com.abc.ui.card.CardRecyclerAdapter.onViewAttachedToWindow(CardRecyclerAdapter.java:398)
at android.support.v7.widget.RecyclerView.dispatchChildAttached(RecyclerView.java:6758)
at android.support.v7.widget.RecyclerView$5.addView(RecyclerView.java:696)
at android.support.v7.widget.ChildHelper.addView(ChildHelper.java:107)
at android.support.v7.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:7697)
at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:7655)
at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:7643)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1539)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1488)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:585)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3506)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3254)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3767)
at android.view.View.layout(View.java:18799)
at android.view.ViewGroup.layout(ViewGroup.java:5952)
at com.abc.ui.core.refresh.LegacySwipeRefreshLayout.onLayout(LegacySwipeRefreshLayout.java:337)
at android.view.View.layout(View.java:18799)
at android.view.ViewGroup.layout(ViewGroup.java:5952)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:18799)
at android.view.ViewGroup.layout(ViewGroup.java:5952)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:18799)
at android.view.ViewGroup.layout(ViewGroup.java:5952)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:18799)
at android.view.ViewGroup.layout(ViewGroup.java:5952)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:18799)
at android.view.ViewGroup.layout(ViewGroup.java:5952)
at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1193)
at android.view.View.layout(View.java:18799)
at android.view.ViewGroup.layout(ViewGroup.java:5952)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:18799)
at android.view.ViewGroup.layout(ViewGroup.java:5952)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:18799)
at android.view.ViewGroup.layout(ViewGroup.java:5952)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:822)
at android.view.View.layout(View.java:18799)
at android.view.ViewGroup.layout(ViewGroup.java:5952)
I managed to sovle this with adding this line
recyclerView.setOnFlingListener(null);
before
snapHelper.attachToRecyclerView(recyclerView);
You can check for OnFlingListener on the RecyclerView first before you add it
if (recycler.getOnFlingListener() == null)
snapHelper.attachToRecyclerView(recycler);
All you have to do is place
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
inside onCreateViewHolder instead of onBindViewHolder
This happens because you're setting the SnapPagerHelper
twice somehow. Note that if you have a RecyclerView
inside another RecyclerView
, this should only happen in each other's constructors or Kotlin's init {}
block (once per item).
My case is quite similar to yours since I have a big vertical RecyclerView
and a small RecyclerView
within.
Code that will cause the exception:
fun bind(value: ArrayList<Item>) {
listAdapter = ItemCellDelegate(value)
val manager = LinearLayoutManager(itemView.context)
manager.orientation = LinearLayoutManager.HORIZONTAL
horizontalRecyclerView?.apply {
layoutManager = manager
adapter = listAdapter
setHasFixedSize(true)
}
val snapHelper: SnapHelper = PagerSnapHelper()
snapHelper.attachToRecyclerView(horizontalRecyclerView)
}
Correct code using init {}
block:
init {
val snapHelper: SnapHelper = PagerSnapHelper()
snapHelper.attachToRecyclerView(horizontalRecyclerView)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With