RecyclerView 列表项动画
原文:http://xingrz.me/2014/2014-11-02/recycler-view-item-animation.html
正当我还在为毕业设计和两个课程大作业烦得焦头烂额之际…我又忍不住写了几行代码。
RecyclerView 还带来了一个新特性:列表项动画(Item Animation)。同时自带了一个动画器是DefaultItemAnimator,大致上的效果就是挤开前后的列表项然后淡入(反之亦然)。
topicsView.setItemAnimator(new DefaultItemAnimator());
没错,如果你还是用 notifyDataSetChanged() 来通告数据集变更的话,你只会看到全部列表项一起淡出再淡入的效果。既然是列表项的动画,那么粒度当然要足够小:具体到某一项的增加、删除、移动、变更。于是 RecyclerView.Adapter 增加了下面几个方法:
-
notifyItemInserted(position) - 有一个新项插入到了 position 位置
-
notifyItemRangeInserted(position, count) - 在 position 位置插入了 count 个新项目
-
notifyItemRemoved(position)
-
notifyItemRangeRemoved(position, count)
-
notifyItemChanged(position)
-
notifyItemMoved(from, to)
-
...
然后呢…考虑到 RecyclerView 目前就只有一个十分基本的 RecyclerView.Adapter,作为一个不折腾不舒服星人 (:зゝ∠),于是我自己仿照 ArrayAdapter 的做法用 List 接口实现了一个ArrayRecyclerAdapter,里面将这些方法都封装好了。
/* ... */
@Override
public void add(int location, E object) {
synchronized (lock) {
list.add(location, object);
notifyItemInserted(location);
}
}
@Override
public boolean add(E object) {
synchronized (lock) {
int lastIndex = list.size();
if (list.add(object)) {
notifyItemInserted(lastIndex);
return true;
} else {
return false;
}
}
}
@Override
public boolean addAll(int location, Collection<? extends E> collection) {
synchronized (lock) {
if (list.addAll(location, collection)) {
notifyItemRangeInserted(location, collection.size());
return true;
} else {
return false;
}
}
}
@Override
public boolean addAll(Collection<? extends E> collection) {
synchronized (lock) {
int lastIndex = list.size();
if (list.addAll(collection)) {
notifyItemRangeInserted(lastIndex, collection.size());
return true;
} else {
return false;
}
}
}
/* ... */
嗯,好像没什么好说的。