我彷彿在逗我笑,就算繼承了,還是要呼叫setanimator方法,這樣還是會建立viewholder
那麼,自己給view設定動畫是否可以呢?
我們知道,recyclerview是通過notifyitem來改變item的狀態的,這就是傳說中的觀察者模式,那麼我們沒有
notifyitemchanged,就算設定了view的動畫,但是item沒有改變,高度也不會變化。
少年, 你還年輕,跟著page繼續解讀。那麼從最基礎的開始
首先設定:setitemanimator,這個似乎沒什麼看的
public
void
setitemanimator(itemanimator animator)
mitemanimator = animator;
if (mitemanimator != null)
}
嗯,重新設定的時候把listener給取消
2. 接下來我們看看這個animator在**初始化的
itemanimator mitemanimator = new defaultitemanimator();
嗯,有乙個預設的動畫
3. 動畫是在哪開啟的呢?
private runnable mitemanimatorrunner = new runnable()
mpostedanimatorrunner = false;
}};
交給runnable去執行
private
void
postanimationrunner()
}private
void
@nullable itemholderinfo prelayoutinfo, @nonnull itemholderinfo postlayoutinfo)
}private
void
@nonnull itemholderinfo prelayoutinfo, @nullable itemholderinfo postlayoutinfo)
}private
void
animatechange(@nonnull viewholder oldholder, @nonnull viewholder newholder,
@nonnull itemholderinfo preinfo, @nonnull itemholderinfo postinfo,
oldholder.setisrecyclable(false);
addanimatingview(oldholder);
}if (oldholder != newholder)
oldholder.mshadowedholder = newholder;
addanimatingview(oldholder);
mrecycler.unscrapview(oldholder);
newholder.setisrecyclable(false);
newholder.mshadowingholder = oldholder;
}if (mitemanimator.animatechange(oldholder, newholder, preinfo, postinfo))
}
有三個地方呼叫到了postanimationrunner,要繼續跟蹤下去,略微複雜,page還無法做到三路線程同時執行,so,先緩一緩,我們先看看這個動畫到底是做了什麼的。
// 清除
private arraylistmpendingremovals = new arraylist<>();
// 新增
private arraylistmpendingadditions = new arraylist<>();
// 移動
private arraylistmpendingmoves = new arraylist<>();
// 改變
private arraylistmpendingchanges = new arraylist<>();
private arraylist> madditionslist = new arraylist<>();
private arraylist> mmoveslist = new arraylist<>();
private arraylist> mchangeslist = new arraylist<>();
private arraylistmaddanimations = new arraylist<>();
private arraylistmmoveanimations = new arraylist<>();
private arraylistmremoveanimations = new arraylist<>();
private arraylistmchangeanimations = new arraylist<>();
private
static
class
moveinfo
}private
static
class
changeinfo
private
changeinfo(viewholder oldholder, viewholder newholder,
int fromx, int fromy, int tox, int toy)
}
從這裡可以看到,這個animator對所有的viewholder都有乙個快取
@override
public
void
runpendinganimations()
// first, remove stuff
for (viewholder holder : mpendingremovals)
mpendingremovals.clear();
// next, move stuff
if (movespending)
moves.clear();
mmoveslist.remove(moves);}};
if (removalspending) else
}// next, change stuff, to run in parallel with move animations
if (changespending)
changes.clear();
mchangeslist.remove(changes);}};
if (removalspending) else
}// next, add stuff
if (additionspending)
additions.clear();
madditionslist.remove(additions);}};
if (removalspending || movespending || changespending) else
}}
先移除,然後移動,再然後改變,最後新增。
在這些操作中,都可以看見迴圈的存在
我竟然在endanimation中發現了乙個todo
// todo if some other animations are chained to end, how do we cancel them as well?
大致介紹完,我們具體來看看每個操作都做了啥
移除
// first, remove stuff
for (viewholder holder : mpendingremovals)
mpendingremovals.clear();
private
void
animateremoveimpl(final viewholder holder)
@override
public
void
onanimationend(view view)
}).start();
}
只是乙個簡單的alpha 變為0,在動畫結束後又設定alpha為1
這不相當於沒有改變嗎?少年,你還是太簡單了,如果這個view不在這上面了,那設定alpha=1又有什麼關係?當然這只是我的乙個推斷而已,具體是否是這樣,之後再看。
private
void
@nonnull itemholderinfo prelayoutinfo, @nullable itemholderinfo postlayoutinfo)
}
這個方法是返回true的,
@override
public
boolean
animateremove(final viewholder holder)
也就是說,在動畫開啟前,先把viewholder加入animator的快取集合中,再開啟動畫
先到這裡吧,國慶之後再繼續
RecyclerView 資料預載入動畫
1.空布局 2.adapter定義兩個變數乙個表示有資料的布局,乙個表示無資料的布局 private static final int type only font 0 文字 private static final int empty view 1 空布局3.重寫adaper中的getitemvi...
RecyclerView常見的問題以及解決方案
2018第乙個星期過了,第一篇部落格東拼西湊出來了,之前的部落格一直都是東拼西湊總結別人的內容,我暫時沒有什麼原創,就記錄一下平時開發中遇到的問題吧,也算是進步的開始了。以下詳細描述問題以及解決方法 這個問題主要是由於inflate方法引數不正確引起的。layoutinflate.inflate 方...
RecyclerView詳解 自定義動畫
如果覺得自定義比較繁瑣,github上也有相關的動畫實現 接下來我們將一步步分析這個實現類,最後在它的基礎上修改預設的動畫效果。先來看defaultitemanimator中的幾個重要的方法 void runpendinganimations 當有動畫需要執行時呼叫。boolean isrunnin...