错误日志如下
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)
原因
在onBindViewHolder中将item的rootview设置了新的RecyclerView.LayoutParams。RecyclerView视图实际上将ViewHolder存储在一个自定义的LayoutParams类中, 所以重置LayoutParams时,ViewHolder引用消失了, 之后会导致NullPointerException。出错做法如下:
@Override
public void onBindViewHolder(Holder holder, final int position) {
holder.iv.setImageDrawable(apps.get(position).getIcon());
holder.tv.setText(apps.get(position).getLabel());
RecyclerView.LayoutParams param = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, recyclerView.getHeight() / ROW_NUM);
holder.layout.setLayoutParams(param);
}
正确的做法
在onCreateViewHolder中设置宽高
@Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.app_item, parent, false);
v.getLayoutParams().height = recyclerView.getHeight() / ROW_NUM;
return new Holder(v);
}