自定义RecyclerView动画——实现remove飞出效果
生活随笔
收集整理的这篇文章主要介绍了
自定义RecyclerView动画——实现remove飞出效果
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
目录
前言
创建ItemAnimator
处理重叠
总结
源码
前言
我们经常会遇到在一个list中删除一条数据,这时候一般会有一个飞出的动画效果,如下图: 在RecyclerView中可以通过setItemAnimator函数设置一个ItemAnimator,实现item的add、remove、change等动作的动效。下面我们就通过ItemAnimator来实现上面的效果。创建ItemAnimator
首先创建一个类,继承至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是一个抽象类,需要实现几个函数。
因为我们要实现是一个remove的动作,需要在animateRemove中处理。这里我们参照DefaultItemAnimator的做法,首先需要两个list,然后在animateRemove将holder添加进list中,这里暂时不做处理,如下:
处理重叠
这是因为我们目前只定义了remove的效果,实际上不仅有飞出的动作还有一个上移的动作,所以还需要定义一下move的效果,同remove一样需要两个list,在animateMove函数中将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实际上就已经上移了,所以在animateMove中设置item的translationY使其保持在未上移的位置。 然后同样在runPedingAnimations中处理,这时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同样是自定义的一个函数,代码如下:
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(); } 执行了一个属性动画,修改了item的translationY使其上移回原位置。同时注意修改isRunning函数,如下: @Override public boolean isRunning() {return !(removeHolders.isEmpty() && removeAnimators.isEmpty() && moveHolders.isEmpty() && moveAnimators.isEmpty()); }这样就实现了一开始的飞出效果。
总结
总结一下,其实自定义ItemAnimator比较简单,虽然代码接近百行,但其实主要就是执行动画。需要注意的就是有些情况需要配合move的动作。 自定义ItemAnimator后,直接为RecyclerView设置即可: list.setItemAnimator(new FlyAnimator());设置后如果调用了adapter的notifyItemRemoved函数就会执行remove的动效。
源码
关注公众号:BennuCTech,发送“FlyAnimator”获取完整源码
总结
以上是生活随笔为你收集整理的自定义RecyclerView动画——实现remove飞出效果的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 自动规避代码陷阱——自定义Lint规则
- 下一篇: java中四种线程池及poolSize、