自从升级到Android支持23.2.0后,有几位开发人员报告了以下堆栈跟踪:
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.support.v7.widget.RecyclerView$ViewHolder.shouldIgnore()' on a null object reference
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2913)
at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1445)
at android.support.v7.widget.RecyclerView.access$400(RecyclerView.java:144)
at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:282)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:821)
at android.view.Choreographer.doCallbacks(Choreographer.java:606)
at android.view.Choreographer.doFrame(Choreographer.java:575)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:807)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6895)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
当启用RecyclerView的更改动画并且调用相应的RecyclerView.Adapter方法notifyItemInserted(),notifyItemRemoved()等时,会发生这种情况,表明对适配器管理的列表进行了单独的更改(而不是批发更改,由notifyDataSetChanged())。
表示这是由于RecyclerView中的错误,还是开发人员做错了什么?
答案 0 :(得分:6)
这似乎是由于RecyclerView中的一个错误引起的,该错误是在23.2.0中引入的。该错误已被报告here,我解释了我认为导致comment #5错误的错误。
以下是我的解释,为了历史目的而复制到这里以便于参考:
我找到了这个问题的根源。内 RecyclerView.dispatchLayoutStep3(),有一个for循环," for(int i = 0;我<计数; ++ i)",其中count是基于 mChildHelper.getChildCount()。虽然这个迭代正在发生,但是 由ChildHelper管理的集合由。修改 ChildHelper.hideViewInternal(),返回null 从第3050行的mChildHelper.getChildAt()调用 RecyclerView,反过来导致返回null getChildViewHolderInt()在同一行代码上(RecyclerView:3050)。
这是导致修改的方法调用链 打破了for循环的完整性:
dispatchLayoutStep3() - > animateChange() - > addAnimatingView() - > hide() - > hideViewInternal()
当ChildHelper将子参数添加到其mHiddenViews集合时, 它违反了for循环的完整性 dispatchLayoutStep3()。
我看到了两个解决方法:
1)在RecyclerView中禁用更改动画
2)降级到23.1.1,这不是一个问题
答案 1 :(得分:5)
在我的情况下,错误是因为我将新的RecyclerView.LayoutParams设置为项目的rootview 。
然后我意识到RecyclerView项目视图实际上将他们的ViewHolders存储在自定义的LayoutParams类中。 因此,当我重置LayoutParams ViewHolder时,引用将永远消失。这会导致NullPointerException以后崩溃。
我停止将RecyclerView.LayoutParams设置为项目rootView后,问题就消失了。 :)
<强>因此。停止在ViewHolder中执行此操作:
RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
itemRoot.setLayoutParams(params);
答案 2 :(得分:3)
如果您绝对需要修改布局参数,可以使用默认的项目布局参数,如下所示:
ViewGroup.LayoutParams params = itemView.getLayoutParams();
params.height=xx;
params.width= xx;
params.yyyy = xxx;
itemView.setLayoutParams(params);
答案 3 :(得分:1)
我刚才遇到了这个例外,我通过将framgent
更改为FragmentLayout
来解决此问题。
我的适配器在fragment参数中使用了一些数据,xml中的using fragment
没有填充数据,因此发生了错误。
只需在此发布,也许对某人有用。
答案 4 :(得分:0)
即使使用RecyclerView 27.1.1版本,我也遇到了这个问题。 我的项目中有以下代码:
recyclerView.setLayoutManager(mLayoutManager);
SimpleItemAnimator itemAnimator = new DefaultItemAnimator();
itemAnimator.setSupportsChangeAnimations(false);
recyclerView.setItemAnimator(itemAnimator);
LayoutInflater inflater = LayoutInflater.from(getContext());
在将Animator添加到RecyclerView之后,我已对其进行了修复,即此代码开始看起来如下:
recyclerView.setLayoutManager(mLayoutManager);
LayoutInflater inflater = LayoutInflater.from(getContext());
答案 5 :(得分:0)
请检查您的 recyclerview 不在孩子的layout.xml