更新于2015年1月4日(底部)
我有一个示例项目,用于演示此功能https://github.com/dbleicher/recyclerview-grid-quickreturn。但以下几点细节可能会对您有所帮助。
当您向RecyclerView添加/删除项目时,应调用notifyItemInserted/notifyItemRemoved,以便适配器告诉布局管理器重新布局受影响的视图。例如,在适配器中:
public void addItemAtPosition(int position, String item) {
myDataset.add(position, item);
mAdapter.notifyItemInserted(position);
}
如果您调用此方法添加视图,并且该视图在屏幕上,则SGLM似乎按预期插入并调整布局。但是,如果您查看列表顶部并在位置零添加项目,则该视图将在屏幕外创建(您将无法看到它)。 您可以使用以下代码滚动到此视图:
public void addItemAtPosition(int position, String item) {
myDataset.add(position, item);
mAdapter.notifyItemInserted(position);
mSGLM.scrollToPosition(position);
}
在StaggeredGridLayoutManager中存在一个错误,当添加“屏幕外”项目时会显露出来。根据yiğit boyar在此线程
https://plus.google.com/u/1/111532428576115387787/posts/6xxayUBz2iV中的评论所述:“如果超出范围添加了一个项目,布局管理器就不会关心它”。这就是错误出现的地方。使用SGLM时,重新布局发生的时间有问题。在我的示例代码(上面的链接)中,我有一个ItemDecorator,它为最上面的项目添加边距,以便它们不被工具栏遮挡。当使用上述代码时,布局在插入新项目时错误地保留了移动“向下”屏幕的项目的边距。很遗憾。这是添加到顶部之前的布局:
以下是添加顶部项目后演示错误的布局:
有一个解决方法,但它有点违背使用RecyclerView的目的。基本上,如果您在添加/删除后只调用notifyDataSetChanged,这将导致SGLM无效化整个布局。从效率角度来看,这并不理想,但确实会得到正确的布局。使用以下代码:
public void addItemAtPosition(int position, String item) {
myDataset.add(position, item);
mAdapter.notifyDataSetChanged();
mSGLM.scrollToPosition(position);
}
这将产生正确的添加后布局:
希望这能帮到你。
更新:2014-01-04
如评论中所述,另一个解决方法是在插入操作后调用RecyclerView的invalidateItemDecorations()。目前,立即在插入操作后调用该方法会忽略此调用(可能是因为已经正在进行布局传递)。如果稍微延迟一下再调用该方法,它似乎确实可以工作:
public void addItemAtPosition(int position, String item) {
myDataset.add(position, item);
mAdapter.notifyItemInserted(position);
mSGLM.scrollToPosition(position);
if (position < columnCount) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mRecycler.invalidateItemDecorations();
}
}, 300);
}
}