RecyclerView 更新Item闪烁问题

问题:

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();的动画保留要怎么做呢?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,593评论 25 709
  • 这篇文章分三个部分,简单跟大家讲一下 RecyclerView 的常用方法与奇葩用法;工作原理与ListView比...
    LucasAdam阅读 4,496评论 0 27
  • 北京-台北 春秋航空从石家庄-台北,机票最便宜加上税700多,官网订。北京到石家庄正定机场的火车票也包含在里面啦。...
    v伟伟v阅读 1,128评论 0 51
  • 全家人的口腔健康就靠它了,――蜂胶漱口水,本人和全家人都是这款漱口水是受益者,用到现在没出现过口腔问题,觉得省心了...
    雨天印记阅读 183评论 0 0
  • 手机摄影爱好者 纯属兴趣
    YANGXIA呐阅读 134评论 0 0