android - 在不重新填充的情况下更新 GridView/ListView

标签 android android-listview android-gridview android-adapter

每当您更新 GridView/ListView 时,您都会在适配器上调用 notifyDatasetChanged,它会使用新数据重新填充列表,删除列表中当前存在的所有内容。

现在拿这个小 video例如来自 L Preview 设计指南

是否有可能实现同样的效果,您看到的唯一变化是适配器重新加载时新项目没有任何“闪烁”,或者这是现在只能在 L 中完成的事情吗?

添加新笔记时,也可以在 Google Keep 应用中找到此效果

最佳答案

恐怕这都是视觉欺骗 - 也就是动画。

...removing everything that was currently in the list.

实际上,没有。

notifyDataSetChanged 仅告知底层观察者数据已更改。而已。作为响应,getView(...)每个可见 View 调用 - ListView#getChildCount() 可访问的数量。由于任一索引已更改(添加/删除项目),或者这些索引处的对象中保存的数据已(^)更改(一个或多个项目已更改),因此通过随后调用 可以直观地(^)刷新数据ListView#getView(...)

'Android Developers' 有一个有趣的视频解释了如何产生您想要的效果:DevBytes: ListView Cell Insertion Animation .

视频/示例仅讨论单项插入。但它应该可以扩展到所有具有一定时间和数学技能的数据操作。

我能够扩展示例代码以插入多个项目。我将动画更改为更简单的 alpha 淡入。单击 Add row 按钮向 ListView 添加一个随机数(介于 1 和 3 之间)的项目。这是它的样子:

enter image description here

伪工作流:

  • 在将新项目传递给适配器之前,遍历 ListView 中的所有可见项目并保存它们的边界(在 Rect 中)和快照(在 BitmapDrawables 中) )

  • 将项目传递给适配器

  • 向 ListView 的 ViewTreeObserver 添加一个 OnPreDrawListener

  • onPreDraw(...) 被调用时,新项目就可以被绘制了。我们可以使用带有相应索引的 ListView#getChildAt(...) 访问它们的 views

  • 所有新项目都设置为不可见,并分配了 alpha 动画师

  • 所有旧项目都分配了 translation_y 动画师

  • 不再可以通过 getChildAt(..) 访问的项目 - 因为添加了新项目 - 被分配了 translation_y 动画师 - 使它们离开屏幕(或超出 ListView 边界) )

  • translation_y 动画师被解雇了。当这些动画师完成运行时,alpha 动画师将启动。

请注意,动画类型(alpha、平移、缩放或这些的任意组合)相对无关紧要。我想这在 GridViewStaggeredGridView(保持)的情况下会更难 - 只是因为数学将涉及 X < em> 和 Y。不过,工作流程应该保持不变。

(^) - 语法不正确,但很自然。

关于android - 在不重新填充的情况下更新 GridView/ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25373971/

相关文章:

java - 无法在下一个屏幕上看到汉堡菜单

Android翻转图片动画

java - 用于日历 View 的 GridView

android - 单击 RecyclerView 列表项

android - 具有不同宽度的不同 View 的高级 StaggeredGridView

安卓 : How to create a customizable time table like structure with scrolling

java - 如何检测Android中正在播放的文件的路径(无论是从内部播放还是从URL流播放)?

android - 使用 Google 地方信息 API

android - 仅为 ListView 中的可见行下载图像

android - 在 fragment 中单击按钮后填充 ListView