RecyclerView.Adapter.notifyItemChanged()永远不会将有效负载传递给onBindViewHolder() [英] RecyclerView.Adapter.notifyItemChanged() never passes payload to onBindViewHolder()

查看:80
本文介绍了RecyclerView.Adapter.notifyItemChanged()永远不会将有效负载传递给onBindViewHolder()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试更新RecyclerView中的ViewHolder,而无需重新绑定整个内容.根据文档,我应该通过调用RecyclerView.Adapter.notifyItemChanged(int position, Object payload)来做到这一点,其中payload是将传递给RecyclerView.Adapter.onBindViewHolder(VH holder, int position, List<Object> payloads)的任意对象,在这里我将能够更新ViewHolder.

I'm trying to update a ViewHolder in a RecyclerView without rebinding the entire thing. According to the docs, I should do this by calling RecyclerView.Adapter.notifyItemChanged(int position, Object payload), where payload is an arbitrary object that will be passed to RecyclerView.Adapter.onBindViewHolder(VH holder, int position, List<Object> payloads), where i'll be able to update the ViewHolder.

但是当我尝试此操作时,onBindViewHolder总是收到一个空列表.在这两个调用之间,将清除内部有效负载列表.在RecyclerView的源代码上设置断点后,发生这种情况是由于重新布局,最终会调用RecyclerView.ViewHolder.clearPayload()

But when I try this, onBindViewHolder always receives an empty list. Between these two calls, the internal list of payloads is cleared. After setting breakpoints at the source code of RecyclerView, this happens because of a relayout, which eventually calls RecyclerView.ViewHolder.clearPayload()

还有其他人设法使它正常工作吗?这是支持库中的错误,还是我完成了触发这两个功能之间的重新布局的事情?

Has anyone else managed to get this working? Is this a bug in the support library or is something I've done triggering a relayout between these two functions?

这是清除有效负载时的堆栈跟踪:

Here's the stack trace for when the payload is cleared:

"<1> main@831692616832" prio=5 runnable
  java.lang.Thread.State: RUNNABLE
      at android.support.v7.widget.RecyclerView$ViewHolder.clearPayload(RecyclerView.java:8524)
      at android.support.v7.widget.RecyclerView$ViewHolder.resetInternal(RecyclerView.java:8553)
      at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4544)
      at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4461)
      at android.support.v7.widget.LayoutState.next(LayoutState.java:86)
      at android.support.v7.widget.StaggeredGridLayoutManager.fill(StaggeredGridLayoutManager.java:1423)
      at android.support.v7.widget.StaggeredGridLayoutManager.onLayoutChildren(StaggeredGridLayoutManager.java:610)
      at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2847)
      at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3145)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:581)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
      at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
      at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1043)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
      at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
      at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
      at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
      at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
      at android.view.View.layout(View.java:14289)
      at android.view.ViewGroup.layout(ViewGroup.java:4562)
      at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1976)
      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1730)
      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
      at android.view.Choreographer.doCallbacks(Choreographer.java:562)
      at android.view.Choreographer.doFrame(Choreographer.java:532)
      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
      at android.os.Handler.handleCallback(Handler.java:730)
      at android.os.Handler.dispatchMessage(Handler.java:92)
      at android.os.Looper.loop(Looper.java:137)
      at android.app.ActivityThread.main(ActivityThread.java:5103)
      at java.lang.reflect.Method.invokeNative(Method.java:-1)
      at java.lang.reflect.Method.invoke(Method.java:525)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
      at dalvik.system.NativeStart.main(NativeStart.java:-1)

推荐答案

RecyclerView默认为

RecyclerView by default creates another copy of the ViewHolder in order to fade the views into each other. This causes the problem because the old ViewHolder gets the payload but then the new one doesn't. So you need to explicitly tell it to reuse the old one:

DefaultItemAnimator animator = new DefaultItemAnimator() {
        @Override
        public boolean canReuseUpdatedViewHolder(RecyclerView.ViewHolder viewHolder) {
            return true;
        }
    };
mRecyclerView.setItemAnimator(animator);

这篇关于RecyclerView.Adapter.notifyItemChanged()永远不会将有效负载传递给onBindViewHolder()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆