Mar*_*say 16 android recycler-adapter android-recyclerview
我试图在RecyclerView一个StaggeredGridLayoutManager带有两列的a中显示三个(至少是我遇到问题的情况).第一项跨越两行.这是它的样子:

现在,我将项目"项目2"移到顶部.这是我在适配器中调用的代码(这是我编写的一个示例,用于演示我在一个更复杂的项目中遇到的问题):
private int findById(int id) {
for (int i = 0; i < items.size(); ++i) {
if (items.get(i).title.equals("Item " + id)) {
return i;
}
}
return -1;
}
// Moving the item "Item 2" with id = 2 and position = 0
public void moveItem(int id, int position) {
final int idx = findById(id);
final Item item = items.get(idx);
if (position != idx) {
items.remove(idx);
items.add(position, item);
notifyItemMoved(idx, position);
//notifyDataSetChanged();
}
}Run Code Online (Sandbox Code Playgroud)
之后,阵列很好:[Item 2, Item 1, Item 3].但是,观点远非如此:

如果我触摸RecyclerView(足够触发过卷效果,如果没有足够的项目可以滚动),则项目2向左移动,我希望在第一个位置看到它(带有漂亮的动画):

正如您在代码中看到的那样,我试图notifyItemMoved(idx, position)通过调用替换notifyDataSetChanged().它有效,但变化不是动画.
我写了一个完整的示例来演示这个并将它放在GitHub上.它几乎是最小的(有移动项目和切换其跨越的选项).
我不明白我做错了什么.这是一个错误StaggeredGridLayoutManager吗?我想避免,notifyDataSetChanged()因为我想保持动画的一致性.
编辑:经过一些挖掘,不需要一个完全跨越的项目来显示问题.我删除了全跨度.当我尝试将第2项移动到位置0时,它不会移动:第1项跟在它后面,第3项在右边移动,所以我有:空单元格,第2项,新行,第1项,第3项滚动后我仍然有正确的布局.
更有趣的是我没有问题GridLayoutManager.我需要一个全范围的项目,所以它不是一个解决方案,但我想这确实是一个错误StaggeredGridLayoutManager...
Moj*_*osh 12
我没有完整的答案,但我可以指出你的解决方法和错误报告(我相信是相关的).
诀窍更新布局,使它看起来像你的第二个屏幕,是调用invalidateSpanAssignments()上StaggeredGridLayoutManger(sglm)你叫后notifyItemMoved()."挑战"是,如果你立即调用它nIM(),它将无法运行.如果你将呼叫延迟几毫秒,它就会.因此,在您引用的MainActivity代码中,我创建sglm了一个私有字段:
private StaggeredGridLayoutManager sglm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new Adapter();
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
sglm = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(sglm);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
}
Run Code Online (Sandbox Code Playgroud)
在switch块中,在一个处理程序中引用它:
case R.id.move_sec_top:
adapter.moveItem(2, 0);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
sglm.invalidateSpanAssignments();
}
}, 100);
return true;
Run Code Online (Sandbox Code Playgroud)
结果是您的动画仍然运行,布局以您希望的方式结束.这是一个真正的kludge,但它确实有效.我相信这是我在以下链接中发现并报告的相同错误:
https://code.google.com/p/android/issues/detail?id=93156
虽然我的"症状"和所需的呼叫是不同的,但潜在的问题似乎是相同的.
祝好运!
编辑:无需postdelayed,只需发布即可:
case R.id.move_sec_top:
adapter.moveItem(2, 0);
new Handler().post(new Runnable() {
@Override
public void run() {
sglm.invalidateSpanAssignments();
}
});
return true;
Run Code Online (Sandbox Code Playgroud)
我最初的理论是,在布局通过结束之前,通话被阻止了,但我相信情况并非如此.相反,我现在认为,如果你invalidateSpanAssignments()立即调用,它实际上执行得太快(在布局更改完成之前).因此,上面的帖子(没有延迟)只是将调用添加到渲染队列的末尾,在布局之后它发生.
| 归档时间: |
|
| 查看次数: |
14164 次 |
| 最近记录: |