首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RecyclerView、StaggeredGridLayoutManager刷新错误

RecyclerView、StaggeredGridLayoutManager刷新错误
EN

Stack Overflow用户
提问于 2014-11-11 16:50:19
回答 2查看 8.6K关注 0票数 15

我使用的是支持库v7-21,但RecyclerView不能正确显示。GridLayoutManagerLinearLayoutManager都没问题。只有当我在StaggeredGridLayoutManager中加载DataSet然后刷新数据时,才会出现问题。数据刷新工作正常,但RecyclerView的视图存在于屏幕之外。

有谁知道如何修复它吗?

EN

回答 2

Stack Overflow用户

发布于 2015-01-03 23:43:31

更新2015-01-04 (底部)

我在https://github.com/dbleicher/recyclerview-grid-quickreturn上有一个示例项目来演示这一点。但这里有一些更多的细节可能会对你有所帮助。

当您向RecyclerView添加/移除一个项目时,您应该调用notifyItemInserted/notifyItemRemoved,让适配器告诉布局管理器仅重新布局受影响的视图。例如,在适配器中:

代码语言:javascript
复制
public void addItemAtPosition(int position, String item) {
    myDataset.add(position, item);
    mAdapter.notifyItemInserted(position);        
}

如果调用此方法来添加视图,并且视图在屏幕上,则SGLM似乎可以按预期插入和调整布局。但是,如果您正在查看列表的顶部,并且将项目添加到零位置,则该视图将在屏幕外创建(并且您将看不到它)。您可以使用以下代码滚动到此视图:

代码语言:javascript
复制
public void addItemAtPosition(int position, String item) {
    myDataset.add(position, item);
    mAdapter.notifyItemInserted(position);
    mSGLM.scrollToPosition(position);
}

在StaggeredGridLayoutManager中有一个错误,在“屏幕外”添加项目时会暴露出来。根据来自yiğ的评论,它在这个帖子https://plus.google.com/u/1/111532428576115387787/posts/6xxayUBz2iV

"...if项目被添加到边界之外,布局管理器不关心“

这就是bug出现的地方。对于SGLM,当重新布局发生时,存在计时问题。在我的示例代码(上面的链接)中,我有一个ItemDecorator,它将页边距添加到最上面的项目,这样它们就不会被工具栏遮挡。使用上面的代码时,当插入新项目时,布局会错误地将此边距保留在屏幕上向下移动的项目上。真扫兴。

下面是在顶部添加之前的布局:

下面的布局演示了在顶部添加一项后的bug:

有一个变通方法,但它在某种程度上违背了使用RecyclerView的目的。基本上,如果你只是在添加/删除之后调用notifyDataSetChanged,这将使SGLM的整个布局无效。从效率的角度来看,这并不是最优的,但它确实会产生一个适当的布局。使用以下代码:

代码语言:javascript
复制
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

正如注释中所指出的,另一种解决方法是在执行插入后在回收器视图上调用invalidateItemDecorations()。现在,在插入之后立即执行此操作似乎会忽略此调用(可能是因为布局过程已经在运行)。如果有人短暂地推迟了通话,它似乎确实起作用了:

代码语言:javascript
复制
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);
    }
}
票数 9
EN

Stack Overflow用户

发布于 2018-01-08 17:18:11

我发现的一个简单的解决方案是,当您将适配器设置为回收器视图时,必须重新设置布局管理器。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26860875

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档