drakeet / MultiType

Flexible multiple types for Android RecyclerView.
Apache License 2.0
5.76k stars 751 forks source link

Bug report , 当 ItemViewBinder 为初始化时,在内部调用 getAdapter 报空指针 #175

Closed chinnsenn closed 7 years ago

chinnsenn commented 7 years ago
Info:
Description:

我的项目中有一个显示图片宫格的界面,起初列表没有数据,调用相机拍照后,回调图片路径去加载,我想在自定义的「PhotoItemViewBinder」中添加图片,但调用 getAdapter 抛出 adapter 的空指针异常。

Reproduction Steps:

MultiTypeAdapter mAdapter = new MultiTypeAdapter(); PhotoItemViewBinder mPhotoItemViewBinder = new PhotoItemViewBinder(); mAdapter.register(Photo.class, mPhotoItemViewBinder); Items item = new Items(); mAdapter.setItems(item); rv.setAdapter(mAdapter);

初始化 items 中没有数据。

My thoughts:

我当然可以在回调后 Activity 调用 mAdapter 去添加照片,但是我想在 PhotoItemViewBinder 中封装了添加图片的方法,但由于 item 中是没有数据的,所以对应的 mPhotoItemViewBinder 没有内部还没初始化也就没有 adapter(我的测试也验证了我的猜想) 还测试到,即使在 item 中加入数据,如果 recycleview 为 gone 的话,在 itemviewbinder 的继承类中 调用 getAdapter 也为 null 。 INVISIBLE 正常。

What did I do:

我也不知道这算不算 bug ,大神看看能不能在没有数据的情况下也初始化 ItemViewBinder ,或者说如果这样做不太好,可以拦截抛出的异常,说清楚异常。

drakeet commented 7 years ago

感谢反馈,但设计如此。ItemViewBinder 中的 adapter 是在 adapter.onCreateViewHolder(...) 被绑定的,如果你一个 item 都没有,自然不会调用 onCreateViewHolder(...),也不会调用 ItemViewBinder。我不知道你如何在此之前于 ItemViewBinder 中调用 getAdapter() 方法的。

或者换句话说:为什么你一个 item 都没有,却触发在 ItemViewBinder 中调用 getAdapter()?你如何做到的?请提供相关代码。

chinnsenn commented 7 years ago

很简单,我在 PhotoItemViewBinder 的继承类中封装了添加图片的方法,方法中有调用 getAdapter() 去刷新布局。而 mPhotoItemViewBinder 已经在 Activity 实例化了,当然可以调用我自己加的方法,但还没有 adapter.onCreateViewHolder(...)。 我封装原因是为了代码复用,也算是一个意外的发现,找了好久才发现是这个原因。所以我想,为了避免其他人遇到同样问题,应该在这样情况下捕获这个异常,并给出更精确的错误提示。

drakeet commented 7 years ago

抱歉,我不太明白你在说什么,请提供相关代码。你为什么要在 onCreateViewHolder 之前调用 getAdapter()?MultiType 已经运行一年多了,第一次有人遇到你这样的情况,难以想象你的场景。

虽说你的场景我难以理解,但 getAdapter() 照你这么说,确实有可能为空,当没有任何 item 时而强制在外界调用它。对此确实可以在 getAdapter() 时进行检测和异常提示。

drakeet commented 7 years ago

我刚思考了一番,大概是理解你的场景了,确实需要避免用户在外界通过 binder 来取 adapter 并出现空指针问题。感谢你的反馈和帮助!

drakeet commented 7 years ago

已经进行了防范和加了误用提醒了。从 v3.3.2 起,用户将能够在 register 之后立马由 ItemViewBinder 获得非空的、与其绑定的 adapter 对象,而不用等到 MultiTypeAdapter 调用 onCreateViewHolder 才进行绑定 adapter。

chinnsenn commented 7 years ago

感谢!