public abstract class SimpleItemAnimator extends RecyclerView.ItemAnimator
It uses RecyclerView.ItemAnimator.ItemHolderInfo
to track the bounds information of the Views. If you would like
to
extend this class, you can override RecyclerView.ItemAnimator.obtainHolderInfo()
method to provide your own info
class that extends RecyclerView.ItemAnimator.ItemHolderInfo
.
RecyclerView.ItemAnimator.AdapterChanges, RecyclerView.ItemAnimator.ItemAnimatorFinishedListener, RecyclerView.ItemAnimator.ItemHolderInfo
FLAG_APPEARED_IN_PRE_LAYOUT, FLAG_CHANGED, FLAG_INVALIDATED, FLAG_MOVED, FLAG_REMOVED
Constructor and Description |
---|
SimpleItemAnimator() |
Modifier and Type | Method and Description |
---|---|
abstract boolean |
animateAdd(RecyclerView.ViewHolder holder)
Called when an item is added to the RecyclerView.
|
boolean |
animateAppearance(RecyclerView.ViewHolder viewHolder,
RecyclerView.ItemAnimator.ItemHolderInfo preLayoutInfo,
RecyclerView.ItemAnimator.ItemHolderInfo postLayoutInfo)
Called by the RecyclerView when a ViewHolder is added to the layout.
|
abstract boolean |
animateChange(RecyclerView.ViewHolder oldHolder,
RecyclerView.ViewHolder newHolder,
int fromLeft,
int fromTop,
int toLeft,
int toTop)
Called when an item is changed in the RecyclerView, as indicated by a call to
RecyclerView.Adapter.notifyItemChanged(int) or
RecyclerView.Adapter.notifyItemRangeChanged(int, int) . |
boolean |
animateChange(RecyclerView.ViewHolder oldHolder,
RecyclerView.ViewHolder newHolder,
RecyclerView.ItemAnimator.ItemHolderInfo preInfo,
RecyclerView.ItemAnimator.ItemHolderInfo postInfo)
Called by the RecyclerView when an adapter item is present both before and after the
layout and RecyclerView has received a
RecyclerView.Adapter.notifyItemChanged(int) call
for it. |
boolean |
animateDisappearance(RecyclerView.ViewHolder viewHolder,
RecyclerView.ItemAnimator.ItemHolderInfo preLayoutInfo,
RecyclerView.ItemAnimator.ItemHolderInfo postLayoutInfo)
Called by the RecyclerView when a ViewHolder has disappeared from the layout.
|
abstract boolean |
animateMove(RecyclerView.ViewHolder holder,
int fromX,
int fromY,
int toX,
int toY)
Called when an item is moved in the RecyclerView.
|
boolean |
animatePersistence(RecyclerView.ViewHolder viewHolder,
RecyclerView.ItemAnimator.ItemHolderInfo preInfo,
RecyclerView.ItemAnimator.ItemHolderInfo postInfo)
Called by the RecyclerView when a ViewHolder is present in both before and after the
layout and RecyclerView has not received a
RecyclerView.Adapter.notifyItemChanged(int) call
for it or a RecyclerView.Adapter.notifyDataSetChanged() call. |
abstract boolean |
animateRemove(RecyclerView.ViewHolder holder)
Called when an item is removed from the RecyclerView.
|
boolean |
canReuseUpdatedViewHolder(RecyclerView.ViewHolder viewHolder)
When an item is changed, ItemAnimator can decide whether it wants to re-use
the same ViewHolder for animations or RecyclerView should create a copy of the
item and ItemAnimator will use both to run the animation (e.g. cross-fade).
|
void |
dispatchAddFinished(RecyclerView.ViewHolder item)
Method to be called by subclasses when an add animation is done.
|
void |
dispatchAddStarting(RecyclerView.ViewHolder item)
Method to be called by subclasses when an add animation is being started.
|
void |
dispatchChangeFinished(RecyclerView.ViewHolder item,
boolean oldItem)
Method to be called by subclasses when a change animation is done.
|
void |
dispatchChangeStarting(RecyclerView.ViewHolder item,
boolean oldItem)
Method to be called by subclasses when a change animation is being started.
|
void |
dispatchMoveFinished(RecyclerView.ViewHolder item)
Method to be called by subclasses when a move animation is done.
|
void |
dispatchMoveStarting(RecyclerView.ViewHolder item)
Method to be called by subclasses when a move animation is being started.
|
void |
dispatchRemoveFinished(RecyclerView.ViewHolder item)
Method to be called by subclasses when a remove animation is done.
|
void |
dispatchRemoveStarting(RecyclerView.ViewHolder item)
Method to be called by subclasses when a remove animation is being started.
|
boolean |
getSupportsChangeAnimations()
Returns whether this ItemAnimator supports animations of change events.
|
void |
onAddFinished(RecyclerView.ViewHolder item)
Called when an add animation has ended on the given ViewHolder.
|
void |
onAddStarting(RecyclerView.ViewHolder item)
Called when an add animation is being started on the given ViewHolder.
|
void |
onChangeFinished(RecyclerView.ViewHolder item,
boolean oldItem)
Called when a change animation has ended on the given ViewHolder.
|
void |
onChangeStarting(RecyclerView.ViewHolder item,
boolean oldItem)
Called when a change animation is being started on the given ViewHolder.
|
void |
onMoveFinished(RecyclerView.ViewHolder item)
Called when a move animation has ended on the given ViewHolder.
|
void |
onMoveStarting(RecyclerView.ViewHolder item)
Called when a move animation is being started on the given ViewHolder.
|
void |
onRemoveFinished(RecyclerView.ViewHolder item)
Called when a remove animation has ended on the given ViewHolder.
|
void |
onRemoveStarting(RecyclerView.ViewHolder item)
Called when a remove animation is being started on the given ViewHolder.
|
void |
setSupportsChangeAnimations(boolean supportsChangeAnimations)
Sets whether this ItemAnimator supports animations of item change events.
|
canReuseUpdatedViewHolder, dispatchAnimationFinished, dispatchAnimationsFinished, dispatchAnimationStarted, endAnimation, endAnimations, getAddDuration, getChangeDuration, getMoveDuration, getRemoveDuration, isRunning, isRunning, obtainHolderInfo, onAnimationFinished, onAnimationStarted, recordPostLayoutInformation, recordPreLayoutInformation, runPendingAnimations, setAddDuration, setChangeDuration, setMoveDuration, setRemoveDuration
public boolean getSupportsChangeAnimations()
public void setSupportsChangeAnimations(boolean supportsChangeAnimations)
#animateChange(ViewHolder, ViewHolder, int, int, int, int)
implementation.
The value of this property is true by default.supportsChangeAnimations
- true if change animations are supported by
this ItemAnimator, false otherwise. If the property is false,
the ItemAnimator
will not receive a call to
#animateChange(ViewHolder, ViewHolder, int, int, int,
int)
when changes occur.RecyclerView.Adapter.notifyItemChanged(int)
,
RecyclerView.Adapter.notifyItemRangeChanged(int, int)
public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder)
Note that this method will only be called if the RecyclerView.ViewHolder
still has the same
type (RecyclerView.Adapter.getItemViewType(int)
). Otherwise, ItemAnimator will always receive
both RecyclerView.ViewHolder
s in the
#animateChange(ViewHolder, ViewHolder, ItemHolderInfo, ItemHolderInfo)
method.
If your application is using change payloads, you can override
#canReuseUpdatedViewHolder(ViewHolder, List)
to decide based on payloads.
canReuseUpdatedViewHolder
in class RecyclerView.ItemAnimator
viewHolder
- The ViewHolder which represents the changed item's old content.setSupportsChangeAnimations(boolean)
public boolean animateDisappearance(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ItemAnimator.ItemHolderInfo preLayoutInfo, @Nullable RecyclerView.ItemAnimator.ItemHolderInfo postLayoutInfo)
RecyclerView.ItemAnimator
This means that the View was a child of the LayoutManager when layout started but has
been removed by the LayoutManager. It might have been removed from the adapter or simply
become invisible due to other factors. You can distinguish these two cases by checking
the change flags that were passed to
#recordPreLayoutInformation(State, ViewHolder, int, List)
.
Note that when a ViewHolder both changes and disappears in the same layout pass, the
animation callback method which will be called by the RecyclerView depends on the
ItemAnimator's decision whether to re-use the same ViewHolder or not, and also the
LayoutManager's decision whether to layout the changed version of a disappearing
ViewHolder or not. RecyclerView will call
animateChange
instead of animateDisappearance
if and only if the ItemAnimator
returns false
from
canReuseUpdatedViewHolder
and the
LayoutManager lays out a new disappearing view that holds the updated information.
Built-in LayoutManagers try to avoid laying out updated versions of disappearing views.
If LayoutManager supports predictive animations, it might provide a target disappear
location for the View by laying it out in that location. When that happens,
RecyclerView will call #recordPostLayoutInformation(State, ViewHolder)
and the
response of that call will be passed to this method as the postLayoutInfo
.
ItemAnimator must call #dispatchAnimationFinished(ViewHolder)
when the animation
is complete (or instantly call #dispatchAnimationFinished(ViewHolder)
if it
decides not to animate the view).
animateDisappearance
in class RecyclerView.ItemAnimator
viewHolder
- The ViewHolder which should be animatedpreLayoutInfo
- The information that was returned from
#recordPreLayoutInformation(State, ViewHolder, int, List)
.postLayoutInfo
- The information that was returned from
#recordPostLayoutInformation(State, ViewHolder)
. Might be
null if the LayoutManager did not layout the item.RecyclerView.ItemAnimator.runPendingAnimations()
is requested,
false otherwise.public boolean animateAppearance(@NonNull RecyclerView.ViewHolder viewHolder, @Nullable RecyclerView.ItemAnimator.ItemHolderInfo preLayoutInfo, @NonNull RecyclerView.ItemAnimator.ItemHolderInfo postLayoutInfo)
RecyclerView.ItemAnimator
In detail, this means that the ViewHolder was not a child when the layout started but has been added by the LayoutManager. It might be newly added to the adapter or simply become visible due to other factors.
ItemAnimator must call #dispatchAnimationFinished(ViewHolder)
when the animation
is complete (or instantly call #dispatchAnimationFinished(ViewHolder)
if it
decides not to animate the view).
animateAppearance
in class RecyclerView.ItemAnimator
viewHolder
- The ViewHolder which should be animatedpreLayoutInfo
- The information that was returned from
#recordPreLayoutInformation(State, ViewHolder, int, List)
.
Might be null if Item was just added to the adapter or
LayoutManager does not support predictive animations or it could
not predict that this ViewHolder will become visible.postLayoutInfo
- The information that was returned from #recordPreLayoutInformation(State, ViewHolder, int, List)
.RecyclerView.ItemAnimator.runPendingAnimations()
is requested,
false otherwise.public boolean animatePersistence(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ItemAnimator.ItemHolderInfo preInfo, @NonNull RecyclerView.ItemAnimator.ItemHolderInfo postInfo)
RecyclerView.ItemAnimator
RecyclerView.Adapter.notifyItemChanged(int)
call
for it or a RecyclerView.Adapter.notifyDataSetChanged()
call.
This ViewHolder still represents the same data that it was representing when the layout started but its position / size may be changed by the LayoutManager.
If the Item's layout position didn't change, RecyclerView still calls this method because
it does not track this information (or does not necessarily know that an animation is
not required). Your ItemAnimator should handle this case and if there is nothing to
animate, it should call #dispatchAnimationFinished(ViewHolder)
and return
false
.
ItemAnimator must call #dispatchAnimationFinished(ViewHolder)
when the animation
is complete (or instantly call #dispatchAnimationFinished(ViewHolder)
if it
decides not to animate the view).
animatePersistence
in class RecyclerView.ItemAnimator
viewHolder
- The ViewHolder which should be animatedpreInfo
- The information that was returned from
#recordPreLayoutInformation(State, ViewHolder, int, List)
.postInfo
- The information that was returned from #recordPreLayoutInformation(State, ViewHolder, int, List)
.RecyclerView.ItemAnimator.runPendingAnimations()
is requested,
false otherwise.public boolean animateChange(@NonNull RecyclerView.ViewHolder oldHolder, @NonNull RecyclerView.ViewHolder newHolder, @NonNull RecyclerView.ItemAnimator.ItemHolderInfo preInfo, @NonNull RecyclerView.ItemAnimator.ItemHolderInfo postInfo)
RecyclerView.ItemAnimator
RecyclerView.Adapter.notifyItemChanged(int)
call
for it. This method may also be called when
RecyclerView.Adapter.notifyDataSetChanged()
is called and adapter has stable ids so that
RecyclerView could still rebind views to the same ViewHolders. If viewType changes when
RecyclerView.Adapter.notifyDataSetChanged()
is called, this method will not be called,
instead, #animateAppearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
will be
called for the new ViewHolder and the old one will be recycled.
If this method is called due to a RecyclerView.Adapter.notifyDataSetChanged()
call, there is
a good possibility that item contents didn't really change but it is rebound from the
adapter. DefaultItemAnimator
will skip animating the View if its location on the
screen didn't change and your animator should handle this case as well and avoid creating
unnecessary animations.
When an item is updated, ItemAnimator has a chance to ask RecyclerView to keep the
previous presentation of the item as-is and supply a new ViewHolder for the updated
presentation (see: #canReuseUpdatedViewHolder(ViewHolder, List)
.
This is useful if you don't know the contents of the Item and would like
to cross-fade the old and the new one (DefaultItemAnimator
uses this technique).
When you are writing a custom item animator for your layout, it might be more performant and elegant to re-use the same ViewHolder and animate the content changes manually.
When RecyclerView.Adapter.notifyItemChanged(int)
is called, the Item's view type may change.
If the Item's view type has changed or ItemAnimator returned false
for
this ViewHolder when #canReuseUpdatedViewHolder(ViewHolder, List)
was called, the
oldHolder
and newHolder
will be different ViewHolder instances
which represent the same Item. In that case, only the new ViewHolder is visible
to the LayoutManager but RecyclerView keeps old ViewHolder attached for animations.
ItemAnimator must call #dispatchAnimationFinished(ViewHolder)
for each distinct
ViewHolder when their animation is complete
(or instantly call #dispatchAnimationFinished(ViewHolder)
if it decides not to
animate the view).
If oldHolder and newHolder are the same instance, you should call
#dispatchAnimationFinished(ViewHolder)
only once.
Note that when a ViewHolder both changes and disappears in the same layout pass, the
animation callback method which will be called by the RecyclerView depends on the
ItemAnimator's decision whether to re-use the same ViewHolder or not, and also the
LayoutManager's decision whether to layout the changed version of a disappearing
ViewHolder or not. RecyclerView will call
animateChange
instead of
animateDisappearance
if and only if the ItemAnimator returns false
from
canReuseUpdatedViewHolder
and the
LayoutManager lays out a new disappearing view that holds the updated information.
Built-in LayoutManagers try to avoid laying out updated versions of disappearing views.
animateChange
in class RecyclerView.ItemAnimator
oldHolder
- The ViewHolder before the layout is started, might be the same
instance with newHolder.newHolder
- The ViewHolder after the layout is finished, might be the same
instance with oldHolder.preInfo
- The information that was returned from
#recordPreLayoutInformation(State, ViewHolder, int, List)
.postInfo
- The information that was returned from #recordPreLayoutInformation(State, ViewHolder, int, List)
.RecyclerView.ItemAnimator.runPendingAnimations()
is requested,
false otherwise.public abstract boolean animateRemove(RecyclerView.ViewHolder holder)
#dispatchRemoveFinished(ViewHolder)
when done, either
immediately (if no animation will occur) or after the animation actually finishes.
The return value indicates whether an animation has been set up and whether the
ItemAnimator's RecyclerView.ItemAnimator.runPendingAnimations()
method should be called at the
next opportunity. This mechanism allows ItemAnimator to set up individual animations
as separate calls to animateAdd()
,
animateMove()
,
animateRemove()
, and
#animateChange(ViewHolder, ViewHolder, int, int, int, int)
come in one by one,
then start the animations together in the later call to RecyclerView.ItemAnimator.runPendingAnimations()
.
This method may also be called for disappearing items which continue to exist in the RecyclerView, but for which the system does not have enough information to animate them out of view. In that case, the default animation for removing items is run on those items as well.
holder
- The item that is being removed.RecyclerView.ItemAnimator.runPendingAnimations()
is requested,
false otherwise.public abstract boolean animateAdd(RecyclerView.ViewHolder holder)
#dispatchAddFinished(ViewHolder)
when done, either
immediately (if no animation will occur) or after the animation actually finishes.
The return value indicates whether an animation has been set up and whether the
ItemAnimator's RecyclerView.ItemAnimator.runPendingAnimations()
method should be called at the
next opportunity. This mechanism allows ItemAnimator to set up individual animations
as separate calls to animateAdd()
,
animateMove()
,
animateRemove()
, and
#animateChange(ViewHolder, ViewHolder, int, int, int, int)
come in one by one,
then start the animations together in the later call to RecyclerView.ItemAnimator.runPendingAnimations()
.
This method may also be called for appearing items which were already in the RecyclerView, but for which the system does not have enough information to animate them into view. In that case, the default animation for adding items is run on those items as well.
holder
- The item that is being added.RecyclerView.ItemAnimator.runPendingAnimations()
is requested,
false otherwise.public abstract boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY)
#dispatchMoveFinished(ViewHolder)
when done, either
immediately (if no animation will occur) or after the animation actually finishes.
The return value indicates whether an animation has been set up and whether the
ItemAnimator's RecyclerView.ItemAnimator.runPendingAnimations()
method should be called at the
next opportunity. This mechanism allows ItemAnimator to set up individual animations
as separate calls to animateAdd()
,
animateMove()
,
animateRemove()
, and
#animateChange(ViewHolder, ViewHolder, int, int, int, int)
come in one by one,
then start the animations together in the later call to RecyclerView.ItemAnimator.runPendingAnimations()
.holder
- The item that is being moved.RecyclerView.ItemAnimator.runPendingAnimations()
is requested,
false otherwise.public abstract boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop)
RecyclerView.Adapter.notifyItemChanged(int)
or
RecyclerView.Adapter.notifyItemRangeChanged(int, int)
.
Implementers can choose whether and how to animate changes, but must always call
#dispatchChangeFinished(ViewHolder, boolean)
for each non-null distinct ViewHolder,
either immediately (if no animation will occur) or after the animation actually finishes.
If the oldHolder
is the same ViewHolder as the newHolder
, you must call
#dispatchChangeFinished(ViewHolder, boolean)
once and only once. In that case, the
second parameter of dispatchChangeFinished
is ignored.
The return value indicates whether an animation has been set up and whether the
ItemAnimator's RecyclerView.ItemAnimator.runPendingAnimations()
method should be called at the
next opportunity. This mechanism allows ItemAnimator to set up individual animations
as separate calls to animateAdd()
,
animateMove()
,
animateRemove()
, and
#animateChange(ViewHolder, ViewHolder, int, int, int, int)
come in one by one,
then start the animations together in the later call to RecyclerView.ItemAnimator.runPendingAnimations()
.
oldHolder
- The original item that changed.newHolder
- The new item that was created with the changed content. Might be nullfromLeft
- Left of the old view holderfromTop
- Top of the old view holdertoLeft
- Left of the new view holdertoTop
- Top of the new view holderRecyclerView.ItemAnimator.runPendingAnimations()
is requested,
false otherwise.public final void dispatchRemoveFinished(RecyclerView.ViewHolder item)
item
- The item which has been removedRecyclerView.ItemAnimator#animateDisappearance(ViewHolder, ItemHolderInfo,
ItemHolderInfo)
public final void dispatchMoveFinished(RecyclerView.ViewHolder item)
item
- The item which has been movedRecyclerView.ItemAnimator#animateDisappearance(ViewHolder, ItemHolderInfo,
ItemHolderInfo)
,
RecyclerView.ItemAnimator#animatePersistence(ViewHolder, ItemHolderInfo, ItemHolderInfo)
,
RecyclerView.ItemAnimator#animateAppearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
public final void dispatchAddFinished(RecyclerView.ViewHolder item)
item
- The item which has been addedpublic final void dispatchChangeFinished(RecyclerView.ViewHolder item, boolean oldItem)
item
- The item which has been changed (this method must be called for
each non-null ViewHolder passed into
#animateChange(ViewHolder, ViewHolder, int, int, int, int)
).oldItem
- true if this is the old item that was changed, false if
it is the new item that replaced the old item.#animateChange(ViewHolder, ViewHolder, int, int, int, int)
public final void dispatchRemoveStarting(RecyclerView.ViewHolder item)
item
- The item being removedpublic final void dispatchMoveStarting(RecyclerView.ViewHolder item)
item
- The item being movedpublic final void dispatchAddStarting(RecyclerView.ViewHolder item)
item
- The item being addedpublic final void dispatchChangeStarting(RecyclerView.ViewHolder item, boolean oldItem)
item
- The item which has been changed (this method must be called for
each non-null ViewHolder passed into
#animateChange(ViewHolder, ViewHolder, int, int, int, int)
).oldItem
- true if this is the old item that was changed, false if
it is the new item that replaced the old item.public void onRemoveStarting(RecyclerView.ViewHolder item)
item
- The ViewHolder being animated.public void onRemoveFinished(RecyclerView.ViewHolder item)
item
- The ViewHolder being animated.public void onAddStarting(RecyclerView.ViewHolder item)
item
- The ViewHolder being animated.public void onAddFinished(RecyclerView.ViewHolder item)
item
- The ViewHolder being animated.public void onMoveStarting(RecyclerView.ViewHolder item)
item
- The ViewHolder being animated.public void onMoveFinished(RecyclerView.ViewHolder item)
item
- The ViewHolder being animated.public void onChangeStarting(RecyclerView.ViewHolder item, boolean oldItem)
item
- The ViewHolder being animated.oldItem
- true if this is the old item that was changed, false if
it is the new item that replaced the old item.public void onChangeFinished(RecyclerView.ViewHolder item, boolean oldItem)
item
- The ViewHolder being animated.oldItem
- true if this is the old item that was changed, false if
it is the new item that replaced the old item.