Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update list in RecyclerView with DiffUtils?

How do you use DiffCallback to load a newList in RecyclerView when DiffUtil ItemCallback is being used.

I would like to give the user the option to return different size lists from the database when the user selects a different size I want the RecyclerView to update.

RecyclerViewAdatper

RecyclerViewAdapter extends ListAdapter<WordEntity, RecyclerViewAdapter.ViewHolder> {
private RecyclerViewAdapter() {
    super(DIFF_CALLBACK);
}

private static final DiffUtil.ItemCallback<WordEntity> DIFF_CALLBACK = new DiffUtil.ItemCallback<WordEntiti>() {

    @Override
    public boolean areItemsTheSame...

    @Override
    public boolean areContentsTheSame...
};

@Override
public viewHolder onCreateViewHolder...

@Override
public void onVindViewHolder ...

class ViewHolder extends RecyclerView.ViewHolder ...

public void updateWordList(List<WordEntity> words) {
    final WordDiffCallBack diffCallBack = new WordDiffCallBack(list???, words);
    final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallBack);

    this.list???.clear();
    this.addAll(words);
    diffResult.dispatcheUpdatesTo(this);
}

WordsDiffCallBack

private final List<WordEntity> mOldList;
private final List<WordEntity> mNewList;

public WordsDiffCallBack(List<WordEntity> oldList, List<WordEntity> newList) {
    this.mOldList = oldList;
    this.mNewList = newList;
}

@Override
public int getOldListSize() {
    return mOldList.size();
}

@Override
public int getNewListSize() {
    return mNewList.size();
}

@Override
public boolean areItemsTheSame(int OldItemPostion, int newItemPosition) ...

@Override boolean areContentsTheSame(int oldItemPosition, int newItemPosition)...

@Override getChangePayload(int oldItemPosition, int newItemPosition) ...
}

I want the RecycelView to update automatically when the size of the list gets changed by the user. How do I call the old list from the ListAdapter and will that even update the RecyclerView

like image 277
Shawn Avatar asked Sep 16 '19 03:09

Shawn


People also ask

How does DiffUtil work?

DiffUtil is a utility class that calculates the difference between two lists and outputs a list of update operations that converts the first list into the second one. It can be used to calculate updates for a RecyclerView Adapter.

How do I use Diffutils with RecyclerView?

Using DiffUtil in RecyclerView Adapter After we know the difference, we update the user list and notify the adapter via dispatchUpdatesTo. dispatchUpdatesTo(this) invokes the adapter and informs it about the views to be updated. Next, we copy the new Data list to the data.

What is DiffUtil callback?

Called by the DiffUtil when it wants to check whether two items have the same data. DiffUtil uses this information to detect if the contents of an item has changed. DiffUtil uses this method to check equality instead of Object#equals(Object) so that you can change its behavior depending on your UI.


1 Answers

You can create a template just like shown in this video in youTube:

https://www.youtube.com/watch?v=y31fzLe2Ajw

Here is an example of adapter.

public class CartFragAdapter extends RecyclerView.Adapter<CartFragAdapter.CartFragViewHolder> {

    private static final String TAG = "debinf PurchaseAdap";

    private static final DiffUtil.ItemCallback<ProductsObject> DIFF_CALLBACK = new DiffUtil.ItemCallback<ProductsObject>() {
        @Override
        public boolean areItemsTheSame(@NonNull ProductsObject oldProduct, @NonNull ProductsObject newProduct) {
            Log.i(TAG, "areItemsTheSame: old is "+oldProduct.getCode()+" ; new is "+newProduct.getCode());
            return oldProduct.getCode().equals(newProduct.getCode());
        }

        @Override
        public boolean areContentsTheSame(@NonNull ProductsObject oldProduct, @NonNull ProductsObject newProduct) {
            Log.i(TAG, "areContentsTheSame: old is "+oldProduct.getPrice()+" ; new is "+newProduct.getPrice());
            return oldProduct.getPrice() == newProduct.getPrice();
        }
    };

    private AsyncListDiffer<ProductsObject> differ = new AsyncListDiffer<ProductsObject>(this, DIFF_CALLBACK);

    @NonNull
    @Override
    public CartFragViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_purchase, parent, false);
        return new CartFragViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull CartFragViewHolder holder, int position) {
        final ProductsObject purchaseList = differ.getCurrentList().get(position);

        holder.mCode.setText(purchaseList.getCode());
        holder.mPrice.setText(String.valueOf(purchaseList.getPrice()));
        holder.mDescription.setText(purchaseList.getDescription());


    }

    @Override
    public int getItemCount() {
        Log.i(TAG, "getItemCount");
        return differ.getCurrentList().size();
    }

    public void submitList(List<ProductsObject> products){
        Log.i(TAG, "submitList: products.size is "+products.size());
        differ.submitList(products);
    }

    public class CartFragViewHolder extends RecyclerView.ViewHolder {

        public TextView mCode, mPrice, mDescription;

        public CartFragViewHolder(@NonNull View itemView) {
            super(itemView);

            mCode = (TextView) itemView.findViewById(R.id.item_productCode);
            mPrice = (TextView) itemView.findViewById(R.id.item_productPrice);
            mDescription = (TextView) itemView.findViewById(R.id.item_productDescription);
        }
    }
}

In MainActivity you call adapter like this:

CartFragAdapter adapter = new CartFragAdapter();
adapter.submitList(inputData);

I hope it helps!

like image 50
Aliton Oliveira Avatar answered Sep 23 '22 10:09

Aliton Oliveira