RecyclerView blinking after notifyDatasetChanged()

前端 未结 18 1668
悲&欢浪女
悲&欢浪女 2020-12-07 16:20

I have a RecyclerView which loads some data from API, includes an image url and some data, and I use networkImageView to lazy load image.

@Override
public vo         


        
相关标签:
18条回答
  • 2020-12-07 16:53

    In Kotlin you can use 'class extension' for RecyclerView:

    fun RecyclerView.disableItemAnimator() {
        (itemAnimator as? SimpleItemAnimator)?.supportsChangeAnimations = false
    }
    
    // sample of using in Activity:
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // ...
        myRecyclerView.disableItemAnimator()
        // ...
    }
    
    0 讨论(0)
  • 2020-12-07 16:55

    Kotlin solution:

    (recyclerViewIdFromXML.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
    
    0 讨论(0)
  • 2020-12-07 16:56

    Hey @Ali it might be late replay. I also faced this issue and solved with below solution, it may help you please check.

    LruBitmapCache.java class is created to get image cache size

    import android.graphics.Bitmap;
    import android.support.v4.util.LruCache;
    import com.android.volley.toolbox.ImageLoader.ImageCache;
    
    public class LruBitmapCache extends LruCache<String, Bitmap> implements
            ImageCache {
        public static int getDefaultLruCacheSize() {
            final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
            final int cacheSize = maxMemory / 8;
    
            return cacheSize;
        }
    
        public LruBitmapCache() {
            this(getDefaultLruCacheSize());
        }
    
        public LruBitmapCache(int sizeInKiloBytes) {
            super(sizeInKiloBytes);
        }
    
        @Override
        protected int sizeOf(String key, Bitmap value) {
            return value.getRowBytes() * value.getHeight() / 1024;
        }
    
        @Override
        public Bitmap getBitmap(String url) {
            return get(url);
        }
    
        @Override
        public void putBitmap(String url, Bitmap bitmap) {
            put(url, bitmap);
        }
    }
    

    VolleyClient.java singleton class [extends Application] added below code

    in VolleyClient singleton class constructor add below snippet to initialize the ImageLoader

    private VolleyClient(Context context)
        {
         mCtx = context;
         mRequestQueue = getRequestQueue();
         mImageLoader = new ImageLoader(mRequestQueue,getLruBitmapCache());
    }
    

    I created getLruBitmapCache() method to return LruBitmapCache

    public LruBitmapCache getLruBitmapCache() {
            if (mLruBitmapCache == null)
                mLruBitmapCache = new LruBitmapCache();
            return this.mLruBitmapCache;
    }
    

    Hope its going to help you.

    0 讨论(0)
  • 2020-12-07 16:56

    Try to use the stableId in recycler view. The following article briefly explains it

    https://medium.com/@hanru.yeh/recyclerviews-views-are-blinking-when-notifydatasetchanged-c7b76d5149a2

    0 讨论(0)
  • According to this issue page ....it is the default recycleview item change animation... You can turn it off.. try this

    recyclerView.getItemAnimator().setSupportsChangeAnimations(false);
    

    Change in latest version

    Quoted from Android developer blog:

    Note that this new API is not backward compatible. If you previously implemented an ItemAnimator, you can instead extend SimpleItemAnimator, which provides the old API by wrapping the new API. You’ll also notice that some methods have been entirely removed from ItemAnimator. For example, if you were calling recyclerView.getItemAnimator().setSupportsChangeAnimations(false), this code won’t compile anymore. You can replace it with:

    ItemAnimator animator = recyclerView.getItemAnimator();
    if (animator instanceof SimpleItemAnimator) {
      ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
    }
    
    0 讨论(0)
  • 2020-12-07 17:02

    for my application, I had some data changing but I didn't want the entire view to blink.

    I solved it by only fading the oldview down 0.5 alpha and starting the newview alpha at 0.5. This created a softer fading transition without making the view disappear completely.

    Unfortunately because of private implementations, I couldn't subclass the DefaultItemAnimator in order to make this change so I had to clone the code and make the following changes

    in animateChange:

    ViewCompat.setAlpha(newHolder.itemView, 0);  //change 0 to 0.5f
    

    in animateChangeImpl:

    oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() { //change 0 to 0.5f
    
    0 讨论(0)
提交回复
热议问题