【问题标题】:An instance of OnFlingListener already set in RecyclerviewRecyclerview 中已经设置了 OnFlingListener 的一个实例
【发布时间】:2017-10-18 00:24:23
【问题描述】:

我在我的 Android 应用中使用了 RecyclerView。我的 RecyclerView 中有很多卡片视图,因此一次只向用户显示 1 个卡片视图。用户必须滑动才能看到下一张卡片。

我遇到了一个问题,即当用户滑动时,recyclerview 会滚动到最后。相反,我需要的是当用户滑动时,向用户显示下一张卡片,如本文所述。

How to make swipe on horizontal recyclerview bring only the next item into view - Android

SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);

我尝试了上面链接中提到的答案。但是当用户滑动时我遇到了一个异常。

请帮我解决。

错误

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)

【问题讨论】:

标签: java android android-recyclerview


【解决方案1】:

我设法通过添加这一行来解决这个问题

recyclerView.setOnFlingListener(null); 

之前

snapHelper.attachToRecyclerView(recyclerView);

【讨论】:

  • 简单易行的解决方案。这可能是一个 hacky 解决方案,但就我看到 SnapHelper 的复杂实现而言,它是最好的解决方案,应该是公认的答案。
  • 同时添加 clearOnScrollListeners() 和 setOnFlingListener(null) 解决了我的问题
  • 如果我再次将数据设置为回收站视图,我会收到此错误,添加setOnFlingListener 会影响recyclerView.addOnScrollListener。第二次设置数据后它没有触发。所以我通过设置参数再次调用我的片段。
  • @NoumanCh 您是否已经解决了您的问题?您对我们如何解决它有什么补充吗?
  • @RikvanVelzen 是的,我已经通过一些我现在不记得的方式解决了。
【解决方案2】:

您可以在添加之前先在 RecyclerView 上检查 OnFlingListener

if (recycler.getOnFlingListener() == null)
        snapHelper.attachToRecyclerView(recycler);

【讨论】:

    【解决方案3】:

    您所要做的就是放置

    SnapHelper snapHelper = new PagerSnapHelper();
    snapHelper.attachToRecyclerView(recyclerView);
    

    onCreateViewHolder 内而不是 onBindViewHolder

    【讨论】:

      【解决方案4】:

      发生这种情况是因为您以某种方式设置了两次SnapPagerHelper。请注意,如果您在另一个 RecyclerView 中有一个 RecyclerView,这应该只发生在彼此的构造函数或 Kotlin 的 init {} 块中(每个项目一次)。
      我的情况和你的很相似,因为我有一个大的垂直RecyclerView 和一个小的RecyclerView

      会导致异常的代码:

       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)
      
      }
      

      使用init {} 块的正确代码:

      init {
          val snapHelper: SnapHelper = PagerSnapHelper()
          snapHelper.attachToRecyclerView(horizontalRecyclerView)
      }
      

      【讨论】:

        【解决方案5】:

        类似这样的:

        override fun onAttachedToWindow(view: RecyclerView) {
            super.onAttachedToWindow(view)
            view.onFlingListener = null;
            StartSnapHelper().attachToRecyclerView(view)
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-01-24
          • 1970-01-01
          • 2019-12-25
          • 1970-01-01
          • 2014-05-27
          • 1970-01-01
          • 1970-01-01
          • 2014-03-30
          相关资源
          最近更新 更多