我通过crashlytics得到了这个堆栈跟踪.我不知道问题出在哪里.
有没有StaggeredGridLayoutManager的替代品,我可以使用它来获得像布局一样的列表视图.
Fatal Exception: java.lang.ArrayIndexOutOfBoundsException: start < 0 || end > len. start=-1, end=11, len=11 at java.util.Arrays.checkStartAndEnd(Arrays.java:1745) at java.util.Arrays.fill(Arrays.java:803) at android.support.v7.widget.StaggeredGridLayoutManager$LazySpanLookup.invalidateAfter(SourceFile:2404) at android.support.v7.widget.StaggeredGridLayoutManager.handleUpdate(SourceFile:1373) at android.support.v7.widget.StaggeredGridLayoutManager.onItemsRemoved(SourceFile:1327) at android.support.v7.widget.RecyclerView$6.dispatchUpdate(SourceFile:725) at android.support.v7.widget.RecyclerView$6.onDispatchFirstPass(SourceFile:716) at android.support.v7.widget.AdapterHelper.dispatchFirstPassAndUpdateViewHolders(SourceFile:316) at android.support.v7.widget.AdapterHelper.dispatchAndUpdateViewHolders(SourceFile:302) at android.support.v7.widget.AdapterHelper.applyRemove(SourceFile:182) at android.support.v7.widget.AdapterHelper.preProcess(SourceFile:103) at android.support.v7.widget.RecyclerView.processAdapterUpdatesAndSetAnimationFlags(SourceFile:2767) at android.support.v7.widget.RecyclerView.onMeasure(SourceFile:2538) at android.view.View.measure(View.java:16521) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5134) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404) at android.widget.LinearLayout.measureVertical(LinearLayout.java:695) at android.widget.LinearLayout.onMeasure(LinearLayout.java:588) at android.view.View.measure(View.java:16521) at android.support.v4.view.ViewPager.onMeasure(SourceFile:1489) at android.view.View.measure(View.java:16521) at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719) at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455) at android.view.View.measure(View.java:16521) at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719) at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455) at android.view.View.measure(View.java:16521) at android.support.v4.widget.DrawerLayout.onMeasure(SourceFile:940) at android.view.View.measure(View.java:16521) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5134) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at android.support.v7.widget.ContentFrameLayout.onMeasure(SourceFile:135) at android.view.View.measure(View.java:16521) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5134) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at android.view.View.measure(View.java:16521) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5134) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at android.view.View.measure(View.java:16521) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5134) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404) at android.widget.LinearLayout.measureVertical(LinearLayout.java:695) at android.widget.LinearLayout.onMeasure(LinearLayout.java:588) at android.view.View.measure(View.java:16521) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5134) at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2331) at android.view.View.measure(View.java:16521) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1925) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1117) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1299) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5739) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761) at android.view.Choreographer.doCallbacks(Choreographer.java:574) at android.view.Choreographer.doFrame(Choreographer.java:544) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5380) at java.lang.reflect.Method.invokeNative(Method.java) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:970) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:786) at dalvik.system.NativeStart.main(NativeStart.java)
这就是我在其中一个适配器中处理单击侦听器所做的工作
@Override public void onBindViewHolder(final ViewHolder holder, final int position) { holder.relative.setClickable(true); holder.relative.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (itemClickListener != null) itemClickListener.onClick(v, position); else AppConfig.log("itemClickLestener was null"); } }); holder.relative.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if (itemClickListener != null) itemClickListener.onLongClick(v, position); return true; } }); return view; }
看起来你试图调用getAdapterPosition()而不计算Recycler View布局(可能由notifyDataSetChanged()调用触发).
总是像这样处理它
final int position = getAdapterPosition(); if(positon != RecyclerView.NO_POSITION){ // you can trust the adapter position // do whatever you intend to do with this position }
文件清楚地说明了以下内容
if you want to access the item in the adapter on a ViewHolder click, you should use getAdapterPosition(). Beware that these methods may not be able to calculate adapter positions if notifyDataSetChanged() has been called and new layout has not yet been calculated. For this reasons, you should carefully handle NO_POSITION or null results from these methods.
UPDATE
现在你终于发布了一些代码.这里有一些你应该考虑的事情.
>不要在onBindViewHolder中传递最终参数.当OnClickListener被触发时,位置不能保证与您认为的相同.这样做
@Override public void onBindViewHolder(ViewHolder holder, int position) { holder.relative.setClickable(true); //do other stuff }
>不要在onBindViewHolder方法中分配任何监听器.随着视图的回收,您最终会将侦听器多次设置为同一视图.而是将其设置在视图持有者类或onCreateViewHolder方法中,如下所示
@Override public MyViewHolder onCreateViewHolder (ViewGroup parent, int viewType) { View myView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.my_layout, parent, false); //setting listeners on creation myView.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { final int position = getAdapterPosition(); if(position != RecyclerView.NO_POSITION){ //do whatever you want with the clicked position } } }); //return the view holder return new MyViewHolder(myView); }
或者在ViewHolder类中
public class MyViewHolder extends RecyclerView.ViewHolder { public MyViewHolder(View itemView) { super(itemView); //setting listeners inside viewHolder class itemView.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { final int position = getAdapterPosition(); if(position != RecyclerView.NO_POSITION){ //do whatever you want with the clicked position } } }); } }
修复上述问题可能会解决您的问题.我强烈建议您查看关于RecyclerView的Google Dev Summit 2015视频.这真的很有趣,他们谈论RecyclerView的细节.他们还提到了为什么不在onBinViewHolder中传递最终参数.单击 here 以查看他们谈论的视频中的确切时刻.
翻译自:https://stackoverflow.com/questions/35577548/recycler-view-fatal-exception-java-lang-arrayindexoutofboundsexception