A. *_*rov 4 android android-recyclerview
制备:
RecyclerView与RecyclerView.Adapter绑定到SQLite Cursor(通过ContentProvider&& Loader)。RecyclerView并根据设计建议RecyclerView.Adapter与之联系。
与建立。SelectionTrackerSelectionTrackerStableIdKeyProvider
第一步-删除项目:
RecyclerViews的项目用长按(欢呼SelectionTracker的SelectionObserver),绘制操作栏右键菜单,消防删除操作,执行SQL删除任务。restartLoader调用进行Cursor Loader更新。onLoadFinished触发,新Cursor获得,调用RecyclerView.Adapter方法notifyDataSetChanged。RecyclerView.Adapter重新绘制RecyclerView内容,一切看起来都很好。第二步-选择其他项目。崩溃:
java.lang.IllegalArgumentException
at androidx.core.util.Preconditions.checkArgument(Preconditions.java:38)
at androidx.recyclerview.selection.DefaultSelectionTracker.anchorRange(DefaultSelectionTracker.java:269)
at androidx.recyclerview.selection.MotionInputHandler.selectItem(MotionInputHandler.java:60)
at androidx.recyclerview.selection.TouchInputHandler.onLongPress(TouchInputHandler.java:132)
at androidx.recyclerview.selection.GestureRouter.onLongPress(GestureRouter.java:96)
at android.view.GestureDetector.dispatchLongPress(GestureDetector.java:779)
at android.view.GestureDetector.access$200(GestureDetector.java:40)
at android.view.GestureDetector$GestureHandler.handleMessage(GestureDetector.java:293)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Run Code Online (Sandbox Code Playgroud)
删除项目进行中时,我在第一步中看到的内容。在StableIdKeyProvider对onDetached ViewHolderitem 执行内部工作时,看ViewHolder不到Adapter中先前分配的位置:
void onDetached(@NonNull View view) {
RecyclerView.ViewHolder holder = mRecyclerView.findContainingViewHolder(view);
int position = holder.getAdapterPosition();
long id = holder.getItemId();
if (position != RecyclerView.NO_POSITION && id != RecyclerView.NO_ID) {
Run Code Online (Sandbox Code Playgroud)
int position 这是 RecyclerView.NO_POSITION
这就是为什么RecyclerView在- StableIdKeyProvider的缓存中包含ID的旧快照而不会影响删除后崩溃的原因。
问题是-为什么?以及如何更新的缓存StableIdKeyProvider?
另一个说明:阅读RecyclerView代码时,我看到以下注释:
Run Code Online (Sandbox Code Playgroud)* Note that if you've called {@link RecyclerView.Adapter#notifyDataSetChanged()}, until the * next layout pass, the return value of this method will be {#NO_POSITION}.
我不明白这句话的确切含义。也许我遇到了描述的情况- notifyDataSetChanged在不适当的时间打电话?或者我需要打两次电话?
PS。对不起,关于文学的描述,有很多复杂的代码
我最终开始使用StableIdKeyProvider并切换到我自己的ItemKeyProvider实现:
new ItemKeyProvider<Long>(ItemKeyProvider.SCOPE_MAPPED) {
@Override
public Long getKey(int position) {
return adapter.getItemId(position);
}
@Override
public int getPosition(@NonNull Long key) {
RecyclerView.ViewHolder viewHolder = recyclerList.findViewHolderForItemId(key);
return viewHolder == null ? RecyclerView.NO_POSITION : viewHolder.getLayoutPosition();
}
}
Run Code Online (Sandbox Code Playgroud)
崩溃消失了,其RecyclerView导航/选择/修改看起来还不错。怎么样StableIdKeyProvider?..可能不是设计用于可变内容的RecyclerView。
| 归档时间: |
|
| 查看次数: |
781 次 |
| 最近记录: |