youth5201314 / banner

🔥🔥🔥Banner 2.0 来了!Android广告图片轮播控件,内部基于ViewPager2实现,Indicator和UI都可以自定义。
Apache License 2.0
12.89k stars 2.51k forks source link

IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionBannerViewHolder #831

Closed lic2050 closed 4 years ago

lic2050 commented 4 years ago

banner: 2.0.10

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionBannerViewHolder{3847bec position=4 id=-1, oldPos=-1, pLpos:-1 no parent} androidx.viewpager2.widget.ViewPager2$RecyclerViewImpl{41de89a VFED..... ........ 0,0-1032,275 #1}, adapter:com.yalla.yalla.main.ui.adapter.BannerAdapter@369ae32, layout:com.youth.banner.util.ScrollSpeedManger@3be9783, context:com.yalla.yalla.main.ui.activity.MainActivity@7e2ce21 at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5998) at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6183) at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288) at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345) at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361) at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368) at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399) at android.os.Handler.handleCallback(Handler.java:907) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:216) at android.app.ActivityThread.main(ActivityThread.java:7625) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

huahuadashen commented 4 years ago

偶现问题 我也出现了

huahuadashen commented 4 years ago

版本是2.0.10 在有刷新数据时 很容易就出现了

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 4(offset:4).state:5 androidx.viewpager2.widget.ViewPager2$RecyclerViewImpl{b725ee9 VFED..... ........ 0,0-1032,180 #2}, adapter:ai.cloudmall.android.user.page.adapter.PackBannerAdapter@9d3976e, layout:com.youth.banner.util.ScrollSpeedManger@44f2e0f, context:ai.cloudmall.android.mvp.ui.activity.MainActivity@3924970 at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6183) at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288) at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345) at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361) at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368) at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:232) at android.app.ActivityThread.main(ActivityThread.java:7240) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:502) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:883)

每次pendingInfos有更新数据 都会重新调用如下代码 mBannerPack?.setAdapter(PackBannerAdapter(activity as Context,pendingInfos)) ?.setOrientation(Banner.VERTICAL) ?.setUserInputEnabled(false) ?.setOnBannerListener(OnBannerListener { data: Any, position: Int -> goCordovaIfLogin(WebViewUtils.ORDER_SHIPPING) }) ?.start()

MoonBlueSky commented 4 years ago

我也出现了这个问题,希望能在源码ScrollSpeedManger复写一下 @Override public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { try { super.onLayoutChildren(recycler, state); } catch (IndexOutOfBoundsException e) { e.printStackTrace(); } } try/catch掉这个问题, 毕竟目前还没有更好的方法,另外一个方法是刷新状态时设置banner不可滑动关闭自动滑动

youth5201314 commented 4 years ago

我反复测试都没有问题啊!我用了十几台云真机测试也都没有问题,你们刷新到底做了啥?不要只发异常啊,贴一下完整的代码看看,或者你们运行下demo,里面也有刷新操作,我都是用demo测试的!

CodeSaid commented 4 years ago

目前也遇到这个问题,网上好像说是应该是在使用recycleView 的adapter.notifyDataSetChange()的时候出现的。 我的理解:应该是在list.clear()后,数据改变,此时重新填充了新数据,此时进行更新,数据改变两次,会导致adapter 刷新的时候出现混乱

CodeSaid commented 4 years ago

解决方法: 在list.clear() 后 就进行adapter.notifyDataSetChange()进行数据刷新。然后在list.addAll() 后,进行adapter.notifyDataSetChange()就可以。但是这样用户体验非常不好,因为在 clear()之后调用adapter.notifyDataSetChange()进行 数据刷新 会造成界面空白

liyujiang-gzu commented 3 years ago

偶尔遇到这个问题,不是必现的

byzyhm commented 11 months ago

BannerAdapter的setDatas改成这样就可以了 public void setDatas(List datas) { if (datas == null) { datas = new ArrayList<>(); } mDatas.clear(); mDatas.addAll(datas); notifyDataSetChanged();

}