39

我有一个布局的 GridView,可以动态添加或删除到网格中。

在 iOS 中,GridView 项目的本机行为是让网格中的其他项目滑动到已删除项目的位置,或者在添加新项目时滑动以腾出空间。

然而,在 Android 上,这种行为只是为了让更改立即出现在屏幕上。我尝试使用 GridView 适配器中的一些技巧向每个 getView() 调用添加自定义动画,但这最终导致了一些问题:

当数据集更改时,Android GridView 在稍后索引的插槽中加载 0 索引项

我尝试让单个视图控制动画而不是适配器的 getView() 方法,但最终结果是相同的。

我还尝试使用 GridLayoutAnimationController,如下所示:

Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.grid_item_fadein);
GridLayoutAnimationController controller = new GridLayoutAnimationController(animation, .2f, .2f);
mGrid.setLayoutAnimation(controller);

这适用于所有 GridView 内容的初始加载,但对该内容的任何更改都会像默认情况下一样立即弹出。

我觉得这是一个非常简单的功能,应该有更简单的方法来做到这一点。我从在线搜索中看到的最好的是一个库,它为 GridView 项目设置动画,这些项目在网格中交换位置,但这不是我想要的(在同一个库中,当你通过删除从网格中删除一个项目时我试图避免的相同即时效果发生)。

我还看到的关于 SO 的常见答案是“看看 APIDemos,有很多例子”。但据我所知,实际上没有动画 GridView 内容更改的示例。

任何帮助表示赞赏,谢谢。

4

4 回答 4

7

Chet Haase 发布了一个关于如何正确处理 ListView 动画的精彩视频。基本概念可以应用于 GridViews。你可以在这里找到视频。

如果您正在为 API 1.0+ 进行开发,您将无法使用视频中提到的引用动画功能(例如ViewPropertyAnimator),除非您使用NineOldAndroids

于 2013-04-26T16:57:01.960 回答
4

在对 GridView 进行任何更改后,如 .remove() 您必须调用mGrid.startLayoutAnimation();

GridView 不会自动为您执行此操作。你必须手动触发它;-)

于 2014-06-12T11:21:49.933 回答
4

我认为对于 AdapterViews,ViewGroup 的 LayoutTransition 不起作用。查看源代码,ViewGroup 确保其他子级的过渡动画发生在调用addViewandremoveView时,但派生的 AdapterView 不使用这些方法,因为它依赖于提供视图的适配器。

上面提到的 Chet Haase 的视频是关于动画正在消失的 ListView 的单个子视图,而不是动画所有其他周围的子视图移动以填补空白。

而且,如果我理解正确的话,GridLayoutAnimationController 是关于孩子们填写时的交错动画(即第一次或整个列表的完整重新布局,从空开始),而不是动画就地布局更改添加或删除后周围的孩子。所以,孩子们是通过淡入或滑入或旋转出现的 - 总是一次一个,从第一个到最后一个。

最后,一个建议的解决方案:如果您不需要基于适配器的视图,您可以切换到 GridLayout 或 LinearLayout。这就是animateLayoutChanges="true"工作的地方,以及“布局动画”演示始终使用的内容。注意 LayoutTransition 需要最低 api 级别 11。而 GridLayout 需要 api14。

于 2013-07-26T19:25:04.410 回答
2

我发现此资源链接对于处理其他布局视图(如 LinearLayout 等)的动画非常有帮助:http: //developer.android.com/training/animation/layout.html 希望这可以提供帮助。您还可以查看https://github.com/nhaarman/ListViewAnimations以获得灵感

于 2013-07-09T22:20:01.187 回答