自定义RecyclerView动画——实现remove飞出效果
生活随笔
收集整理的這篇文章主要介紹了
自定义RecyclerView动画——实现remove飞出效果
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
目錄
前言
創(chuàng)建ItemAnimator
處理重疊
總結(jié)
源碼
前言
我們經(jīng)常會(huì)遇到在一個(gè)list中刪除一條數(shù)據(jù),這時(shí)候一般會(huì)有一個(gè)飛出的動(dòng)畫效果,如下圖: 在RecyclerView中可以通過(guò)setItemAnimator函數(shù)設(shè)置一個(gè)ItemAnimator,實(shí)現(xiàn)item的add、remove、change等動(dòng)作的動(dòng)效。下面我們就通過(guò)ItemAnimator來(lái)實(shí)現(xiàn)上面的效果。創(chuàng)建ItemAnimator
首先創(chuàng)建一個(gè)類,繼承至SimpleItemAnimator,如下: class FlyAnimator extends SimpleItemAnimator{@Overridepublic boolean animateRemove(RecyclerView.ViewHolder holder) {return false;}@Overridepublic boolean animateAdd(RecyclerView.ViewHolder holder) {return false;}@Overridepublic boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {return false;}@Overridepublic boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop) {return false;}@Overridepublic void runPendingAnimations() {}@Overridepublic void endAnimation(RecyclerView.ViewHolder item) {}@Overridepublic void endAnimations() {}@Overridepublic boolean isRunning() {return false;} }SimpleItemAnimator是一個(gè)抽象類,需要實(shí)現(xiàn)幾個(gè)函數(shù)。
因?yàn)槲覀円獙?shí)現(xiàn)是一個(gè)remove的動(dòng)作,需要在animateRemove中處理。這里我們參照DefaultItemAnimator的做法,首先需要兩個(gè)list,然后在animateRemove將holder添加進(jìn)list中,這里暫時(shí)不做處理,如下:
處理重疊
這是因?yàn)槲覀兡壳爸欢x了remove的效果,實(shí)際上不僅有飛出的動(dòng)作還有一個(gè)上移的動(dòng)作,所以還需要定義一下move的效果,同remove一樣需要兩個(gè)list,在animateMove函數(shù)中將holder添加至list中,如下: List<RecyclerView.ViewHolder> moveHolders = new ArrayList<>(); List<RecyclerView.ViewHolder> moveAnimators = new ArrayList<>(); @Override public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {holder.itemView.setTranslationY(fromY - toY);moveHolders.add(holder);return true; } 注意在remove的一瞬間,下方的item實(shí)際上就已經(jīng)上移了,所以在animateMove中設(shè)置item的translationY使其保持在未上移的位置。 然后同樣在runPedingAnimations中處理,這時(shí)runPedingAnimations代碼如下: @Override public void runPendingAnimations() {if(!removeHolders.isEmpty()) {for(RecyclerView.ViewHolder holder : removeHolders) {remove(holder);}removeHolders.clear();}if(!moveHolders.isEmpty()){for(RecyclerView.ViewHolder holder : moveHolders) {move(holder);}moveHolders.clear();} }這里move同樣是自定義的一個(gè)函數(shù),代碼如下:
private void move(final MoveInfo moveInfo){moveAnimators.add(moveInfo);ObjectAnimator animator = ObjectAnimator.ofFloat(moveInfo.holder.itemView,"translationY", moveInfo.holder.itemView.getTranslationY(), 0);animator.setDuration(500);animator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationStart(android.animation.Animator animation) {dispatchMoveStarting(moveInfo.holder);}@Overridepublic void onAnimationEnd(android.animation.Animator animation) {dispatchMoveFinished(moveInfo.holder);moveAnimators.remove(moveInfo.holder);if(!isRunning()) dispatchAnimationsFinished();}});animator.start(); } 執(zhí)行了一個(gè)屬性動(dòng)畫,修改了item的translationY使其上移回原位置。同時(shí)注意修改isRunning函數(shù),如下: @Override public boolean isRunning() {return !(removeHolders.isEmpty() && removeAnimators.isEmpty() && moveHolders.isEmpty() && moveAnimators.isEmpty()); }這樣就實(shí)現(xiàn)了一開始的飛出效果。
總結(jié)
總結(jié)一下,其實(shí)自定義ItemAnimator比較簡(jiǎn)單,雖然代碼接近百行,但其實(shí)主要就是執(zhí)行動(dòng)畫。需要注意的就是有些情況需要配合move的動(dòng)作。 自定義ItemAnimator后,直接為RecyclerView設(shè)置即可: list.setItemAnimator(new FlyAnimator());設(shè)置后如果調(diào)用了adapter的notifyItemRemoved函數(shù)就會(huì)執(zhí)行remove的動(dòng)效。
源碼
關(guān)注公眾號(hào):BennuCTech,發(fā)送“FlyAnimator”獲取完整源碼?
總結(jié)
以上是生活随笔為你收集整理的自定义RecyclerView动画——实现remove飞出效果的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 自动规避代码陷阱——自定义Lint规则
- 下一篇: java中四种线程池及poolSize、