Prithniraj Nicyone
Prithniraj Nicyone

Reputation: 5121

Animation issue after calling notifyitemchanged

I've an ImageView in which image is loaded using Glide. When I've performed the like action then Notify the recycler view adapter using notifyItemChanged(position). It causes the blinks the image 2 times. Can anyone help me here.

This portion of code is executed when the notifyItemChanged(position) is called:

    Glide.with(mContext)
    .load(mainImage)
    .placeholder(R.color.grey_light)
    .diskCacheStrategy(DiskCacheStrategy.ALL)
    .into(listItemHolder.mSingleAttachmentImage);

Thanks in advance.

Upvotes: 5

Views: 1123

Answers (2)

Lait
Lait

Reputation: 190

Solution 1 :

ItemAnimator animator = mRecyclerView.getItemAnimator();
if (animator instanceof SimpleItemAnimator) {
    ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
}

ref https://github.com/bumptech/glide/issues/1599


Solution 2 :

notifyItemChanged(int position) > notifyItemRangeChanged(int positionStart, int itemCount) > notifyItemRangeChanged(positionStart, itemCount, null) ;

/**
         * Notify any registered observers that the item at <code>position</code> has changed with an
         * optional payload object.
         *
         * <p>This is an item change event, not a structural change event. It indicates that any
         * reflection of the data at <code>position</code> is out of date and should be updated.
         * The item at <code>position</code> retains the same identity.
         * </p>
         *
         * <p>
         * Client can optionally pass a payload for partial change. These payloads will be merged
         * and may be passed to adapter's {@link #onBindViewHolder(ViewHolder, int, List)} if the
         * item is already represented by a ViewHolder and it will be rebound to the same
         * ViewHolder. A notifyItemRangeChanged() with null payload will clear all existing
         * payloads on that item and prevent future payload until
         * {@link #onBindViewHolder(ViewHolder, int, List)} is called. Adapter should not assume
         * that the payload will always be passed to onBindViewHolder(), e.g. when the view is not
         * attached, the payload will be simply dropped.
         *
         * @param position Position of the item that has changed
         * @param payload Optional parameter, use null to identify a "full" update
         *
         * @see #notifyItemRangeChanged(int, int)
         */
        public final void notifyItemChanged(int position, Object payload) {
            mObservable.notifyItemRangeChanged(position, 1, payload);
        }

notice @param payload Optional parameter, use null to identify a "full" update

you can use notifyItemChanged(position,position) and do changeView in RecyclerView.Adapter.onBindViewHolder()

Upvotes: 3

danypata
danypata

Reputation: 10175

I think the blink of the image is caused by the ItemAnimator of the RecylerView. I had the same issue and I solved it by adding the default animator and telling the recycler view to reuse the view holder for the animations. Something like this:

theRecyclerView.setItemAnimator(new DefaultItemAnimator() {
        @Override
        public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) {
            return true;
        }

        @Override
        public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull List<Object> payloads) {
            return true;
        }
    });

In this way the RecyclerView can use the same ViewHolder and won't create another one when notifyItemChange is called.

Upvotes: 1

Related Questions