我使用了支持库 v7-21,但RecyclerView
显示不正确。
GridLayoutManager
没关系LinearLayoutManager
。问题仅在StaggeredGridLayoutManager
我加载DataSet
然后刷新数据时发生。数据刷新工作正常,但RecyclerView
的视图存在于屏幕之外。
有谁知道如何解决它?
我使用了支持库 v7-21,但RecyclerView
显示不正确。
GridLayoutManager
没关系LinearLayoutManager
。问题仅在StaggeredGridLayoutManager
我加载DataSet
然后刷新数据时发生。数据刷新工作正常,但RecyclerView
的视图存在于屏幕之外。
有谁知道如何解决它?
2015-01-04 更新(底部)
我在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 似乎可以按预期工作,插入和调整布局。但是,如果您正在查看列表顶部并且在位置 0 处添加项目,则视图将在屏幕外创建(您将看不到它)。您可以使用以下代码滚动到此视图:
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(); // Should NOT do this, but it works!
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);
// Items added to the top row? Better invalidate the decorator.
// Delay to ensure that the previous layout pass has completed.
if (position < columnCount) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mRecycler.invalidateItemDecorations();
}
}, 300);
}
}
我发现一个简单的解决方案是,当您将适配器设置为回收站视图时,您必须再次设置布局管理器。