每当您更新 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 之间)的项目。这是它的样子:
伪工作流:
在将新项目传递给适配器之前,遍历 ListView 中的所有可见项目并保存它们的边界(在
Rect
中)和快照(在BitmapDrawables
中) )将项目传递给适配器
向 ListView 的 ViewTreeObserver 添加一个
OnPreDrawListener
。当
onPreDraw(...)
被调用时,新项目就可以被绘制了。我们可以使用带有相应索引的ListView#getChildAt(...)
访问它们的views
。所有新项目都设置为不可见,并分配了 alpha 动画师
所有旧项目都分配了 translation_y 动画师
不再可以通过
getChildAt(..)
访问的项目 - 因为添加了新项目 - 被分配了 translation_y 动画师 - 使它们离开屏幕(或超出 ListView 边界) )translation_y 动画师被解雇了。当这些动画师完成运行时,alpha 动画师将启动。
请注意,动画类型(alpha、平移、缩放或这些的任意组合)相对无关紧要。我想这在 GridView
或 StaggeredGridView
(保持)的情况下会更难 - 只是因为数学将涉及 X
< em> 和 Y
。不过,工作流程应该保持不变。
(^) - 语法不正确,但很自然。
关于android - 在不重新填充的情况下更新 GridView/ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25373971/