What's wrong with my DiffUtil implementation?

The problem comes from definition of mAdapter. You defined it as RecyclerView.Adapter which is super class of your MyAdapter and it does not contain updateList(). You should change it as following:

private MyAdapter mAdapter;

Updated 1/13/2019:

I have rewrote your adapter with AsyncListDiffer which calculates the diffrence asynchronously then applies it to the adapter.

MyAdapter.java

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.constraint.ConstraintLayout;
import android.support.v7.recyclerview.extensions.AsyncListDiffer;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;   
import com.bumptech.glide.Glide;    
import java.util.List;


public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    private AsyncListDiffer<User> mAsyncListDiffer;

    public static class MyViewHolder extends RecyclerView.ViewHolder {

        public TextView singleItemTextView;
        public ImageView singleItemImage;
        public View layout;
        public ConstraintLayout constraintLayout;

        public MyViewHolder(View v) {
            super(v);
            layout = v;
            singleItemImage = (ImageView) v.findViewById(R.id.icon);
            singleItemTextView = (TextView) v.findViewById(R.id.singleitemtv);
            constraintLayout = (ConstraintLayout) v.findViewById(R.id.nbConstraintLayout);
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter() {
        DiffUtil.ItemCallback<User> diffUtilCallback = new DiffUtil.ItemCallback<User>() {

            @Override
            public boolean areItemsTheSame(@NonNull User newUser, @NonNull User oldUser) {
                return newUser.getUserId().equals(oldUser.getUserId());
            }

            @Override
            public boolean areContentsTheSame(@NonNull User newUser, @NonNull User oldUser) {
                return newUser.equals(oldUser);
            }
        };
        mAsyncListDiffer = new AsyncListDiffer<>(this, diffUtilCallback);
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.nb_image_view, parent, false);
        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        User user = mAsyncListDiffer.getCurrentList().get(position);
        Uri userImage = user.getImageUrl();
        holder.singleItemTextView.setText(user.getUserId());

        Glide.with(holder.itemView.getContext() /* context */)
                .load(userImage)
                .into(holder.singleItemImage);

        holder.constraintLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Context context = v.getContext();
                Intent intent = new Intent(v.getContext(), DisplayUserActivity.class);
                context.startActivity(intent);
            }
        });
    }

    @Override
    public int getItemCount() {
        return mAsyncListDiffer.getCurrentList().size();
    }

    public void updateList(List<User> newList) {
        mAsyncListDiffer.submitList(newList);
    }

}

User.java

public class User {

    private String mUserId;
    private Uri mImageUrl;

    public User(String userId, String imageUrl) {
        mUserId = userId;
        mImageUrl = Uri.parse(imageUrl);
    }

    public String getUserId() {
        return mUserId;
    }

    public Uri getImageUrl() {
        return mImageUrl;
    }

    @Override
    public boolean equals(Object other) {
        if (other instanceof User) {
            User user = (User) other;
            return mUserId.equals(user.getUserId()) && mImageUrl.equals(user.getImageUrl());
        } else {
            return false;
        }
    }

}

In addition to @aminography's answer, I suggest you to use ListAdapter, a RecyclerView.Adapter implementation that makes it easier to update you RecyclerView with the correct animations. This class is included in the recyclerview support library.

Below is an example of usage based on your use case:

public class MyAdapter extends ListAdapter<User, UserViewHolder> {
    public MyAdapter() {
        super(new UserDiffCallback());
    }

    public UserViewHolder onCreateViewHolder(int position, int viewType) { ... }

    public void onBindViewHolder(UserViewModel holder, int position) {
        User userAtPosition = getItem(position); // getItem is a protected method from ListAdapter
        // Bind user data to your holder...
    }
}

public class UserDiffCallback extends DiffUtil.ItemCallback<User> {

    @Override
    public boolean areItemsTheSame(@NonNull User oldUser, @NonNull User newUser) {
        return oldUser.getUserId().equals(newUser.getUserId());
    }

    @Override
    public boolean areContentsTheSame(@NonNull User oldUser, @NonNull User newUser) {
        // No need to check the equality for all User fields ; just check the equality for fields that change the display of your item.
        // In your case, both impact the display.
        return oldUser.getUserId().equals(newUser.getUserId()) 
                && (oldUser.getImageUrl() == null) ? newUser.getImageUrl() == null : oldUser.getImageUrl().equals(newUser.getImageUrl());
    }
}

Then, when you need to update the list with new users, call myAdapter.submitList(newList). Juste like with AsyncListDiffer, the diff between the two list is calculated on a background Thread.


Modify your method:

    public void updateList(ArrayList<User> newList) {
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new MyDiffUtilCallBack(this.mDataset, newList));
        this.mDataSet.clear()
        this.mDataSet.addAll(newList)
        diffResult.dispatchUpdatesTo(this);
    }