How to update Recyclerview using DiffUtil in Android Studio (Java)
Step 1: Create a new layout for an item in my case I named it item_contact.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:background="@color/white" android:layout_marginBottom="4dp" android:layout_height="wrap_content"> <TextView android:id="@+id/id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="24dp" android:layout_marginTop="24dp" android:textSize="16sp" android:textStyle="bold" android:textColor="@color/black" android:text="TextView" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="24dp" android:layout_marginTop="24dp" android:layout_marginBottom="24dp" android:textSize="14sp" android:textColor="@color/black" android:text="TextView" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/id" /> <Button android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="24dp" android:text="Delete" app:layout_constraintBottom_toBottomOf="@+id/name" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@+id/id" /> </androidx.constraintlayout.widget.ConstraintLayout>
Step 2: Create a new model class in my case I named it Contact.java and implement an interface "Comparable" and implement its method "compareTo"
package com.ashish.diffutilsrecyclerview; import java.util.ArrayList; public class Contact implements Comparable { private String id; private String name; private String mobile; public Contact(String id, String name, String mobile) { this.id = id; this.name = name; this.mobile = mobile; } public Contact() { } public ArrayList<Contact> getContactList() { ArrayList<Contact> contact = new ArrayList<Contact>(); contact.add(new Contact("1","Ashish","987")); contact.add(new Contact("2","sdf","786")); contact.add(new Contact("3","sdfg","786")); contact.add(new Contact("4","Assdfghish","76786")); contact.add(new Contact("5","dfg","976787")); contact.add(new Contact("6","sdf","987867")); contact.add(new Contact("7","hth","988677")); contact.add(new Contact("8","rrrd","45")); contact.add(new Contact("9","fdgd","634")); contact.add(new Contact("10","Ashrrvish","987")); contact.add(new Contact("11","rgr","453")); contact.add(new Contact("12","Asrtyhish","453")); contact.add(new Contact("13","rty","8675")); return contact; } public ArrayList<Contact> getUpdateContactList() { ArrayList<Contact> contact = getContactList(); contact.get(2).setName("dfghdfgh"); contact.get(8).setMobile("1111"); contact.get(9).setMobile("1111"); return contact; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } @Override public int compareTo(Object o) { Contact contact = (Contact) o; if (contact.getName().equals(this.name) && contact.getMobile().equals(this.mobile)){ return 0; } return 1; } }
Step 3: Create a new DiffUtil Callback class in my case I name it MyDiffUtilsCallbacks.java and extend it with class "DiffUtil.Callback" and implement its method "getOldListSize", "getNewListSize", "areItemsTheSame", "areContentsTheSame" and "getChangePayload"
package com.ashish.diffutilsrecyclerview; import android.os.Bundle; import androidx.annotation.Nullable; import androidx.recyclerview.widget.DiffUtil; import java.util.ArrayList; public class MyDiffUtilsCallbacks extends DiffUtil.Callback { ArrayList<Contact> oldContacts; ArrayList<Contact> newContacts; public MyDiffUtilsCallbacks(ArrayList<Contact> oldContacts, ArrayList<Contact> newContacts) { this.oldContacts = oldContacts; this.newContacts = newContacts; } @Override public int getOldListSize() { return oldContacts !=null ? oldContacts.size() : 0; } @Override public int getNewListSize() { return newContacts != null ? newContacts.size() : 0; } @Override public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { return true; } @Override public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { int result = newContacts.get(newItemPosition).compareTo(oldContacts.get(oldItemPosition)); if (result==0){ return true; } return false; } @Nullable @Override public Object getChangePayload(int oldItemPosition, int newItemPosition) { Contact newContact = newContacts.get(newItemPosition); Contact oldContact = oldContacts.get(oldItemPosition); Bundle bundle = new Bundle(); if (!newContact.getName().equals(oldContact.getName())){ bundle.putString("name",newContact.getName()); } if (!newContact.getMobile().equals(oldContact.getMobile())){ bundle.putString("mobile",newContact.getMobile()); } if (bundle.size()==0){ return null; } return bundle; } }
Step 4: Create a new Recyclerview Adapter class in my case I named it ContactAdapter.java and extend it with the class "RecyclerView.Adapter" and implement its method "onCreateViewHolder", "onBindViewHolder(@NonNull ContactViewHolder holder, int position)", "onBindViewHolder(@NonNull ContactViewHolder holder, int position, @NonNull List<Object> payloads)", "getItemCount", "getItemCount",
package com.ashish.diffutilsrecyclerview; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import java.util.List; public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactViewHolder> { private ArrayList<Contact> contactArrayList; public ContactAdapter(ArrayList<Contact> contactArrayList) { this.contactArrayList = contactArrayList; } @NonNull @Override public ContactViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new ContactViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_contact, parent, false)); } @Override public void onBindViewHolder(@NonNull ContactViewHolder holder, int position) { Contact contact = contactArrayList.get(position); holder.mobile.setText(contact.getMobile()); holder.name.setText(contact.getName()); holder.button.setOnClickListener(v -> { //code here }); } @Override public void onBindViewHolder(@NonNull ContactViewHolder holder, int position, @NonNull List<Object> payloads) { if (payloads.isEmpty()) { super.onBindViewHolder(holder, position, payloads); }else { Bundle bundle = (Bundle) payloads.get(0); for (String key : bundle.keySet()){ if (key.equals("name")){ holder.name.setText(bundle.getString("name")); } if (key.equals("mobile")){ holder.mobile.setText(bundle.getString("mobile")); } } } } @Override public int getItemCount() { return contactArrayList.size(); } public static class ContactViewHolder extends RecyclerView.ViewHolder { private TextView name; private TextView mobile; private Button button; public ContactViewHolder(@NonNull View itemView) { super(itemView); name = itemView.findViewById(R.id.name); mobile = itemView.findViewById(R.id.id); button = itemView.findViewById(R.id.delete); } } public void updateContact(ArrayList<Contact> newContactList) { DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new MyDiffUtilsCallbacks(contactArrayList,newContactList)); diffResult.dispatchUpdatesTo(this); contactArrayList.clear(); contactArrayList.addAll(newContactList); } }
Step 5: Our activity_main.xml looks like this
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/refresh" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="Refresh" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginTop="2dp" tools:listitem="@layout/item_contact" android:background="#E6E6E6" android:layout_marginBottom="16dp" app:layout_constraintBottom_toTopOf="@+id/refresh" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
Step 6: Our MainActivity.java looks like this
package com.ashish.diffutilsrecyclerview; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.os.Bundle; import android.widget.Button; public class MainActivity extends AppCompatActivity { private RecyclerView recyclerview; private ContactAdapter contactAdapter; private Button refreshButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerview = findViewById(R.id.recyclerview); refreshButton = findViewById(R.id.refresh); recyclerview.setLayoutManager(new LinearLayoutManager(this)); contactAdapter = new ContactAdapter(new Contact().getContactList()); recyclerview.setAdapter(contactAdapter); refreshButton.setOnClickListener(v ->{ contactAdapter.updateContact(new Contact().getUpdateContactList()); }); } }
0 Comments