36

背景

GridView是一个扩展AdapterView的类,这意味着它可以有效地以网格样式显示单元格,当用户滚动旧视图时,它会回收显示为新视图。

问题

有时,您可能希望获得一个特殊的 UI,它类似于 Windows Phone Tiles UI,具有不同大小的单元格。

像这样的东西:

AABB
AACC
AADD
AADD

每个字母代表其单元格的一部分,因此单元格 A 为 2x4 ,单元格 B 和单元格 C 各取 2x1 ,单元格 D 为 2x2 。

它可能不止于此,单元格 D 完成的位置比我所展示的要高一点,而在它的正下方有另一个单元格,因此 D 的末端和 A 的末端不需要对齐。

具有这种风格的应用示例是pinterest

GridView 不允许这样的事情。

事实上,我尝试过的每个解决方案都有问题。想问问有没有其他替代方案或更好的解决方案。

我发现了什么

有多种方法可以处理这个问题:

  1. 作为扩展AdapterView 的类, GridView能够为每个项目设置一个类型(使用BaseAdapter),这将允许您设置单元格的布局方式。

    但是,它仍然会限制您,因为您将获得一排排的项目,一个在另一个之下。你必须让它们对齐。

  2. GridLayout是一种相对较新的布局,而且非常灵活。谷歌已经为它发布了一个很好的兼容性库,支持 API7 及更高版本。

    但是,它不使用任何视图回收,因此如果您希望显示很多项目,这是一个糟糕的选择。

    如果您有很多项目,则需要为它们创建所有视图。

  3. QuiltView 库- 从 GridLayout 扩展,所以基本上有同样的问题。

  4. StaggeredGridView - 看起来最有前途,但有很多错误,尤其是在改变方向时。此类错误包括空单元格、不良滚动和 NPE(很少见但仍然会发生)。我也不确定它是否支持自定义单元格而不是单独的 imageViews。

  5. 其他解决方案,如此所述。

问题

有谁知道这个问题的另一种选择?对于我展示的任何解决方案,也许有一些解决方法?


编辑:我认为关于 StaggeredGridView ,可以通过使用在 getView 中设置其大小的普通 ImageView 来解决滚动和异常。我认为它以一种奇怪的方式工作的原因是样本在从互联网加载后更新了 imageview 的大小。

但是,这个库中仍然存在空单元问题。不仅如此,即使不改变方向,它们的尺寸也会发生很大变化。


编辑:目前,我认为最好的解决方案是使用 PinterestLikeAdapterView 库

它没有我能找到的任何问题。

但是,它不能使项目占用超过 1 个单元格宽度。尽管如此,它还是很好的。

编辑:遗憾的是它与 notifyDataSetChanged 有问题。我在这里报道过。

4

3 回答 3

17

是不是有点晚才回复?

从 etsy 检查这个库。它看起来很有希望。

https://github.com/etsy/AndroidStaggeredGrid

我认为它是https://github.com/maurycyw/StaggeredGridView的较新版本

.

更新。

尝试使用 谷歌的RecyclerView StaggeredGridLayoutManager

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setAdapter(adapter);
于 2014-01-16T16:42:18.610 回答
6

我认为带有StaggeredGridLayoutManager的RecyclerView可以解决这个问题,如果你也想拥有一个快速滚动器,你可以试试这个库

所以,不需要更多的技巧,因为谷歌提供了一个解决方案......

于 2015-03-05T08:11:13.040 回答
0

您可以使用单个 ListView 来完成此操作,其中每个单元格包含不同的网格模板。使用这种技术,我已经完成了与您所描述的类似的事情。如果单元格大小需要唯一,这将不起作用,但对于您描述的情况应该足够了:

AABB
AACC
AADD
AADD

创建一些像这样的模板,具有 A、B、C、D 的各种排列,然后您可以将它们随机用作 ListView 单元格,并且一些简单的偏移数学将允许您的适配器填充每个子单元格以完成以下操作:

AABB
AACC
AADD
AADD

BBBB
ACCC
ADDD
ADDD

AAAA
BBCC
BBCC
DDDD

AABB
AACC
AADD
AADD

AABB
AACC
DDDD
DDDD
于 2013-11-06T18:45:37.000 回答