Gra*_*eme 8 android recycler-adapter android-recyclerview
我在使用该notifyItemMoved()方法时遇到问题.它似乎错误地显示无动于衷的视图.
我的清单中有4个元素.我想要做的是动画项目1和项目3之间的交换.项目1和3交换正确,但项目2显示项目3的内容!
所以列表开始看起来像这样:
Item 0
Item 1
Item 2
Item 3
Run Code Online (Sandbox Code Playgroud)
并以此结束:
Item 0
Item 3
Item 3 <!-- What the heck has this changed for?
Item 1
Run Code Online (Sandbox Code Playgroud)
我的适配器由a支持List mProductList.我调用以下代码:
public void sortBackingListUsingSortingList(List<ProductWrapper> newProductItems) {
Log.e("", "Before:");
for(ProductWrapper wrapper : mProductItems) wrapper.log();
for(int i = 0; i < newProductItems.size(); i++) {
ProductWrapper currentItem = mProductItems.get(i);
ProductWrapper correctItem = newProductItems.get(i);
if(!currentItem.equals(correctItem)) {
// Item in wrong place
int indexOfCorrectItem = getIndexOfItemInList(mProductItems, correctItem);
Collections.swap(mProductItems, i, indexOfCorrectItem);
notifyItemMoved(i, indexOfCorrectItem);
Log.e("", "notifyItemMoved(" + i + ", " + indexOfCorrectItem+")");
Log.e("", "After:");
for(ProductWrapper wrapper : mProductItems) wrapper.log();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我还添加了日志记录以onBindViewHolder检查我的视图逻辑是否被调用:
@Override
public void onBindViewHolder(HolderBasic holder, int position) {
Log.e("", "onBindViewHolder(holder, " + position + ")");
holder.fill(mProductItems.get(position));
}
Run Code Online (Sandbox Code Playgroud)
我的日志看起来像这样:
09-02 14:39:17.853 ? Before:
09-02 14:39:17.853 : Item 0
09-02 14:39:17.853 : Item 1
09-02 14:39:17.853 : Item 2
09-02 14:39:17.853 : Item 3
09-02 14:39:17.854 ? notifyItemMoved(1, 3)
09-02 14:39:17.854 ? After:
09-02 14:39:17.854 : Item 0
09-02 14:39:17.854 : Item 3
09-02 14:39:17.854 : Item 2
09-02 14:39:17.854 : Item 1
09-02 14:39:17.867 ? onBindViewHolder(holder, 1)
09-02 14:39:17.874 ? onBindViewHolder(holder, 3)
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,第2项没有理由改变它的显示 - 然而,确实如此.谁知道为什么?
编辑
我可以通过遍历整个适配器并调用notifyItemChanged()每个项目来绕过上面.效率低而且不是一个好的解决方案,但对用户来说是不可见的.
Gra*_*eme 16
感谢@ david.mihola带领我做错了什么.
这花了很长时间才弄清楚,因为症状没有使问题显而易见!
我这样做:
Collections.swap(mProductItems, i, indexOfCorrectItem);
notifyItemMoved(i, indexOfCorrectItem)
Run Code Online (Sandbox Code Playgroud)
但是,我显然没有想到notifyItemMoved()实际上在做什么.它只是通知适配器项i已移动到indexOfCorrectItem 它不会告诉适配器也indexOfCorrectItem已移动到i.
在幕后,它正在做以下事情:
notifyItemChanged(1); notifyItemChanged(3); 当然,上面的第3项将第3项移至项目2而没有更新的视图!步骤4和5通过使item1和item3正确显示并使item2不正确来隐藏问题!
一旦我意识到这一点,我尝试了以下代码:
notifyItemMoved(indexOfCorrectItem, i);
notifyItemMoved(i, indexOfCorrectItem);
Run Code Online (Sandbox Code Playgroud)
这使列表以正确的顺序排列,但它使动画短路.
所以,相反,我完全抛弃了交换:
mProductItems.remove(indexOfCorrectItem);
mProductItems.add(i, correctItem);
notifyItemMoved(indexOfCorrectItem, i);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6463 次 |
| 最近记录: |