问题:
RecyclerView 调用notifyItemChanged()方法更新单个Item时,此Item有闪烁
源码分析:
在android.support.v7.widget.RecyclerView中:
....
ItemAnimator mItemAnimator = new DefaultItemAnimator();
....
/**
* Gets the current ItemAnimator for this RecyclerView. A null return value
* indicates that there is no animator and that item changes will happen without
* any animations. By default, RecyclerView instantiates and
* uses an instance of {@link DefaultItemAnimator}.
*
* @return ItemAnimator The current ItemAnimator. If null, no animations will occur
* when changes occur to the items in this RecyclerView.
*/
public ItemAnimator getItemAnimator() {
return mItemAnimator;
}
....
/**
* Sets the {@link ItemAnimator} that will handle animations involving changes
* to the items in this RecyclerView. By default, RecyclerView instantiates and
* uses an instance of {@link DefaultItemAnimator}. Whether item animations are
* enabled for the RecyclerView depends on the ItemAnimator and whether
* the LayoutManager {@link LayoutManager#supportsPredictiveItemAnimations()
* supports item animations}.
*
* @param animator The ItemAnimator being set. If null, no animations will occur
* when changes occur to the items in this RecyclerView.
*/
public void setItemAnimator(ItemAnimator animator) {
if (mItemAnimator != null) {
mItemAnimator.endAnimations();
mItemAnimator.setListener(null);
}
mItemAnimator = animator;
if (mItemAnimator != null) {
mItemAnimator.setListener(mItemAnimatorListener);
}
}
....
可以看出RecyclerView 默认实现了一个DefaultItemAnimator,而DefaultItemAnimator继承自SimpleItemAnimator,里面有个方法是:
/**
* Sets whether this ItemAnimator supports animations of item change events.
* If you set this property to false, actions on the data set which change the
* contents of items will not be animated. What those animations do is left
* up to the discretion of the ItemAnimator subclass, in its
* {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)} implementation.
* The value of this property is true by default.
*
* @param 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
* {@link #animateChange(ViewHolder, ViewHolder, int, int, int,
* int)} when changes occur.
* @see Adapter#notifyItemChanged(int)
* @see Adapter#notifyItemRangeChanged(int, int)
*/
public void setSupportsChangeAnimations(boolean supportsChangeAnimations) {
mSupportsChangeAnimations = supportsChangeAnimations;
}
只要设置为false,就可以不显示动画了,也就解决了闪烁问题。 (所有的notifyItem*动画都取消了)
解决办法:
((SimpleItemAnimator)mRecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
疑问:
用上面的方式好像会取消掉所有的动画,如果我只想取消notifyItemChanged()时的动画,其他如notifyItemInserted();的动画保留要怎么做呢?