Recyclerview animation
什麼時候開始的 RecyclerView animation,在我們UI 2.0~3.0的時候,很多地方都需要這種 RecyclerView 界面 初始化
,添加
,移除
,更新
數據的 動畫效果樣式.
看幾個RecycelrView Adapter 初始化的小DEMO
除了這種方式進行初始化,我們還可以用前面所講的過渡動畫來進行
Transition explode = new Explode();
explode.setDuration(1000);
TransitionManager.beginDelayedTransition(recyclerView, explode);
if (recyclerView.getAdapter() != null) {
recyclerView.setAdapter(null);
} else {
recyclerView.setAdapter(mColorsAdapter);
}
再看看 RecyclerView Item 添加,移除,更新的的小栗子
如果沒有設置 Item animation,RecyclerView 默認使用的就是 DefaultItemAnimator(繼承的 SimpleItemAnimator)
。
如果想實現上面的一些效果(Demo地址),我們就需要 自定義自己的 Item Animator ,只需要繼承 SimpleItemAnimator,重寫幾個關鍵的重要函數
函數名 | 含義 |
---|---|
animateRemove |
item 移除時的動畫 |
animateAdd |
item 添加時的動畫 |
animateMove |
移動時的動畫 列表項位置移動時調用 |
animateChange |
item 更新時的動畫 |
runPendingAnimations |
真正控制執行動畫的地方 |
endAnimation |
停止某個Item的動畫 |
endAnimations |
停止所有動畫 |
isRunning |
返回當前是否有動畫需要執行 |
在自定義Item Animator 中會調用到的相關函數:
函數名 | 含義 |
---|---|
dispatch(Add/Remove/Move/Change)Starting |
動畫開始時調用,比如Add dispatchAddStarting |
dispatch(Add/Remove/Move/Change)Finished |
動畫結束時調用,比如Add dispatchAddFinished |
dispatchAnimationsFinished |
所有動畫結束時調用 |
引發 Item 動畫的幾個函數
Adapter.notifyItemInserted(int position) // 觸發 Add Item Animator
Adapter.notifyItemRemoved(int position) // 觸發 Remove Item Animator
Adapter.notifyItemChanged(int position) // 觸發 Change Item Animator
Adapter.notifyItemMoved(int fromPosition, int toPosition) // 觸發 MoveItem Animator
先來自定義的一個添加Item View的動畫效果的小DEMO
public class CumtomAnimator extends SimpleItemAnimator {
// 保存 需要做 add 動畫效果的 itemView 的數組
private ArrayList<RecyclerView.ViewHolder> mPendingAdditions = new ArrayList<>();
@Override
public boolean animateAdd(RecyclerView.ViewHolder holder) {
// 添加對應的數據,主要用於 runPendingAnimations 執行動畫效果
mPendingAdditions.add(holder);
}
@Override
public void runPendingAnimations() {
for (RecyclerView.ViewHolder holder : mPendingAdditions) {
ViewCompat.animate(holder.itemView)
.scaleX(1.0f)
.scaleY(1.0f)
.setDuration(getAddDuration())
.start();
}
// 記得要清理掉,不然其它動畫執行後,要被影響,而且也影響 isRunning 的判斷
mPendingAdditions.clear();
}
@Override
public boolean isRunning() {
return !mPendingAdditions.isEmpty()
|| ... ...
}
... ...
}
ViewCompat:android官方實現兼容的一個幫助類,具體可以查找網上相關資料
官方資料
可以試試(notifyItemInserted(position)
)有沒有動畫效果,肯定是沒有效果的,因爲沒有去初始化它 起始的樣子!!!
來改改代碼… …
... ...
public boolean animateAdd(RecyclerView.ViewHolder holder) {
// 初始化動畫狀態
// 將 ItemView 設置爲 ScaleX,ScaleY 都爲0
// 那麼執行動畫效果的時候,就是從 中間位置 然後 放大 0.0f -> 1.0f
View itemView = holder.itemView;
ViewCompat.setPivotY(itemView, itemView.getMeasuredHeight() / 2);
ViewCompat.setPivotX(itemView, itemView.getMeasuredWidth() / 2);
ViewCompat.setScaleX(itemView, 0);
ViewCompat.setScaleY(itemView, 0);
// 添加對應的數據,主要用於 runPendingAnimations
mPendingAdditions.add(holder);
}
... ...
代碼修改後,添加 ItemView 就能達到下面的效果。
你會發現,上面的 RecyclerView ItemView的添加
動畫效果,還行,就是新增的時候,下面的其它的ItemView 移動的很生硬,所以這裏就引出了 animateMove
函數。
函數名 | 參數 | 參數含義 |
---|---|---|
animateMove | (final ViewHolder holder, int fromX, int fromY, int toX, int toY) | 列表項位置移動時調用,移動的ViewHolder;fromX 起始x,y值;toX 目標x,y值 |
@Override
public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
// 設置它的初始位置.
final View view = holder.itemView;
// 目標的位置 減去 起始位置(原來的位置),得到需要位移的距離
int deltaX = toX - fromX;
int deltaY = toY - fromY;
// 設置後,相當於從 新的位置 回到了 原來的位置上.
if (deltaX != 0) {
ViewCompat.setTranslationX(view, -deltaX);
}
if (deltaY != 0) {
ViewCompat.setTranslationY(view, -deltaY);
}
mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY));
}
@Override
public void runPendingAnimations() {
... ...
// 最後從原來的位置 做動畫,回到新的位置上,就完整了移動的動畫效果.
for (MoveInfo moveInfo : mPendingMoves) {
ViewCompat.animate(moveInfo.holder.itemView)
.translationX(0)
.translationY(0)
.setDuration(getMoveDuration())
.start();
}
mPendingMoves.clear();
... ...
}
整個添加Item View的動畫效果,就這樣完成啦!!!
當然在項目,肯定沒有那麼簡單,這裏只是簡單的舉個小栗子,給大家說明下幾個函數的重要性.
如果是項目中使用,只需要繼承這個 BaseitemAnimator
,寫一些自己想要的效果就OK,不過這裏已經實現了大多數的動畫效果。
需要使用以上效果的小夥伴,自行下載,代碼庫地址
5.x 參考資料
RecyclerView animations 國外大神文章
RecyclerView anim視頻
深入理解 RecyclerView 系列之二:ItemAnimator
自定義RecyclerView ItemAnimator 上
自定義RecyclerView ItemAnimator 下
Android動畫了解—轉場/過渡(Transition) 動畫<=上個章節 下個章節=> Android動畫了解—其它動畫