參考默認(rèn)動畫類DefaultItemAnimator
官方有一個(gè)默認(rèn)Item動畫類DafaultItemAnimator,其中 DefaultItemAnimator 繼承了SimpleItemAnimator 繼承了 RecyclerView.ItemAnimator
- SimpleItemAnimator 它是一個(gè)包裝類,用來判斷當(dāng)前的ViewHolder到底是執(zhí)行移動、移除、添加或者改變等行為。
- DefaultItemAnimator 是執(zhí)行具體動畫類,它負(fù)責(zé)將viewHolder初始化、保存需要執(zhí)行動畫的ViveHolder以及動畫信息、執(zhí)行具體的動畫。 我們自定義ItemAnimtor 也是仿照這個(gè)來的。
- 其中DefaultItemAnimator中 animate + 動作 為名的的方法(比如animateAdd())做的事情有:計(jì)算動畫信息,保存動畫信息,初始化view的狀態(tài),且可以控制該VIewHolder是否執(zhí)行該次動畫,如果返回值為false那么那么不會執(zhí)行該ViewHolder的改次動畫。
- DefaultItemAnimator中animate + 動作 + Impl 為名的方法,做的動作是執(zhí)行具體的動畫動作。
- runPendingAnimations是最終執(zhí)行具體動畫的方法
產(chǎn)生動畫的流程
RecyclerView 的 onLayout 方法主要調(diào)用了 dispatchLayout 方法,dispatchLayout 中保障了 dispatchLayoutStep1、2、3 三個(gè)方法的執(zhí)行。
dispatchLayoutStep1
- 首先將當(dāng)前屏幕中的 items 信息保存;(生成 ItemHolderInfo 賦值給 InfoRecord 的 preInfo 并且對其 flags 添加 FLAG_PRE ,再將 InfoRecord 添加到 ViewInfoStore 的 mLayoutHolderMap 中)
- 進(jìn)行預(yù)布局;(調(diào)用 LayoutManager 的 onLayoutChildren)
- 預(yù)布局完成后和第 1 步中保存的信息對比,將新出現(xiàn)的 item 信息保存;(和第 1 步中不同的是 flags 設(shè)置的是 FLAG_APPEAR)
dispatchLayoutStep2
- 將預(yù)布局 boolean 值改為 flase;
- 進(jìn)行真正布局;(調(diào)用 LayoutManager 的 onLayoutChildren)
dispatchLayoutStep3
- 將真正布局后屏幕上的 items 信息保存;(與 dispatchLayoutStep1 不同的是賦值給 InfoRecord 的 postInfo 并且 flags 添加 FLAG_POST)
- 執(zhí)行動畫,調(diào)用 ViewInfoStore.process();
- 布局完成回調(diào),onLayoutCompleted;
仿照 DefaultItemAnimator 搭建據(jù)圖框架Base框架
public class BaseItemAnimator extends SimpleItemAnimator {
//業(yè)務(wù)控制是否執(zhí)行該viewHolder的動畫 比如通訊錄列表,判斷只有聯(lián)
//系人的ViewHolder執(zhí)行動畫,如果是分組頭部ViewHolder則不執(zhí)行動畫
@Override
public boolean animateRemove(RecyclerView.ViewHolder holder) {
// 計(jì)算 holder的動畫參數(shù) 如:x偏移量 y軸偏移量 透明度等等
// 保存 viewHolder 以及 動畫參數(shù)
// 業(yè)務(wù)控制是否執(zhí)行該viewHolder的動畫
// 比如通訊錄列表,判斷只有聯(lián)系人的ViewHolder執(zhí)行動畫,
// 如果是分組頭部ViewHolder則不執(zhí)行動畫
return false;
}
@Override
public boolean animateAdd(RecyclerView.ViewHolder holder) {
// 計(jì)算 holder的動畫參數(shù) 如:x偏移量 y軸偏移量 透明度等等
// 保存 viewHolder 以及 動畫參數(shù)
// 業(yè)務(wù)控制是否執(zhí)行該viewHolder的動畫
return false;
}
//用于控制添加,移動更新時(shí),其它Item的動畫執(zhí)行
@Override
public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
// 計(jì)算 holder的動畫參數(shù) 如:x偏移量 y軸偏移量 透明度等等
// 保存 viewHolder 以及 動畫參數(shù)
// 業(yè)務(wù)控制是否執(zhí)行該viewHolder的動畫
return false;
}
//Item更新回調(diào)
@Override
public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop) {
// 計(jì)算 holder的動畫參數(shù) 如:x偏移量 y軸偏移量 透明度等等
// 保存 viewHolder 以及 動畫參數(shù)
// 業(yè)務(wù)控制是否執(zhí)行該viewHolder的動畫
return false;
}
//真正控制執(zhí)行動畫的地方
//關(guān)鍵方法,參考DafaultItemAnimator的執(zhí)行,在具體的子方法下面去修改和重載
@Override
public void runPendingAnimations() {
// 根據(jù)保存的 viewHolder 以及 animInfo 執(zhí)行動畫
}
...
}
給 RecyclerView 設(shè)置動畫調(diào)用 setItemAnimator 方法,將自定義的Animator設(shè)置給RecyclerView即可。
參考文章:
https://juejin.cn/post/7169857225949708301
https://www.jianshu.com/p/7171ea362513文章來源:http://www.zghlxwxcb.cn/news/detail-503281.html
源碼:
MultiTypeAdapter文章來源地址http://www.zghlxwxcb.cn/news/detail-503281.html
到了這里,關(guān)于[Android]自定義RecyclerView中View的動畫的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!