From c474130e08c00650ead4dd910c5f42fd76fa7d2d Mon Sep 17 00:00:00 2001 From: Vafeen <666av6@gmail.com> Date: Fri, 7 Feb 2025 23:47:42 +0300 Subject: [PATCH] Add DiffCallback to DrawerLayoutAdapter --- .../ui/Adapters/DrawerLayoutAdapter.java | 47 ++++++++++++++-- .../DrawerLayoutAdapterDiffCallback.java | 54 +++++++++++++++++++ 2 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Adapters/diffUtils/DrawerLayoutAdapterDiffCallback.java diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java index e52016f2253..3929d846ef4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/DrawerLayoutAdapter.java @@ -9,13 +9,15 @@ package org.telegram.ui.Adapters; import android.content.Context; -import android.content.pm.PackageManager; import android.view.View; import android.view.ViewGroup; import androidx.annotation.Keep; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.RecyclerView; +import org.jetbrains.annotations.NotNull; import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.LocaleController; @@ -26,6 +28,7 @@ import org.telegram.tgnet.TLRPC; import org.telegram.ui.ActionBar.DrawerLayoutContainer; import org.telegram.ui.ActionBar.Theme; +import org.telegram.ui.Adapters.diffUtils.DrawerLayoutAdapterDiffCallback; import org.telegram.ui.Cells.DividerCell; import org.telegram.ui.Cells.DrawerActionCell; import org.telegram.ui.Cells.DrawerAddCell; @@ -39,7 +42,7 @@ import java.util.Collections; public class DrawerLayoutAdapter extends RecyclerListView.SelectionAdapter { - + private ArrayList lastItems = new ArrayList<>(); private Context mContext; private DrawerLayoutContainer mDrawerLayoutContainer; private ArrayList items = new ArrayList<>(11); @@ -100,14 +103,23 @@ public boolean isAccountsShown() { } private View.OnClickListener onPremiumDrawableClick; + public void setOnPremiumDrawableClick(View.OnClickListener listener) { onPremiumDrawableClick = listener; } + /** + * Updates the RecyclerView's data set and efficiently refreshes the view using DiffUtil to calculate the minimal set of changes + * based on the differences between the previous and current data. After the update, the current data set is saved as the previous data set + * for the next DiffUtil comparison. + */ @Override public void notifyDataSetChanged() { resetItems(); - super.notifyDataSetChanged(); + DrawerLayoutAdapterDiffCallback diffCallback = new DrawerLayoutAdapterDiffCallback(lastItems, items); + DiffUtil.DiffResult diff = DiffUtil.calculateDiff(diffCallback); + diff.dispatchUpdatesTo(this); + lastItems = (ArrayList) items.clone(); } @Override @@ -190,7 +202,7 @@ public int getItemViewType(int i) { return 4; } else { if (accountNumbers.size() < UserConfig.MAX_ACCOUNT_COUNT) { - if (i == accountNumbers.size()){ + if (i == accountNumbers.size()) { return 5; } else if (i == accountNumbers.size() + 1) { return 2; @@ -413,6 +425,33 @@ public Item(int id, CharSequence text, int icon) { this.text = text; } + /** + * Compares the contents of this Item with another Item to determine if they are visually the same. + * This method is used by DiffUtil to determine if an item in the RecyclerView has been modified + * and needs to be updated. + * + * @param obj The Item to compare this Item to. Returns false if obj is null. + * @return True if the contents of both Items are the same, false otherwise. + */ + public boolean areContentsTheSame(Item obj) { + if (obj == null) { + return false; + } + if (this.icon != obj.icon) { + return false; + } + if (this.text != obj.text) { + return false; + } + if (this.error != obj.error) { + return false; + } + if (this.bot != obj.bot) { + return false; + } + return true; + } + public Item(TLRPC.TL_attachMenuBot bot) { this.bot = bot; this.id = (int) (100 + (bot.bot_id >> 16)); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Adapters/diffUtils/DrawerLayoutAdapterDiffCallback.java b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/diffUtils/DrawerLayoutAdapterDiffCallback.java new file mode 100644 index 00000000000..c340fc33883 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Adapters/diffUtils/DrawerLayoutAdapterDiffCallback.java @@ -0,0 +1,54 @@ +package org.telegram.ui.Adapters.diffUtils; +import androidx.recyclerview.widget.DiffUtil; +import org.telegram.ui.Adapters.DrawerLayoutAdapter; +import java.util.ArrayList; + +/** + * A DiffUtil.Callback implementation for calculating the differences between two lists of + * {@link DrawerLayoutAdapter.Item} objects, specifically for updating the DrawerLayoutAdapter + * efficiently. + */ +public class DrawerLayoutAdapterDiffCallback extends DiffUtil.Callback { + private final ArrayList oldItems; + private final ArrayList newItems; + + public DrawerLayoutAdapterDiffCallback(ArrayList _oldItems, ArrayList _newItems) { + oldItems = _oldItems; + newItems = _newItems; + } + + + @Override + public int getOldListSize() { + return oldItems.size(); + } + + @Override + public int getNewListSize() { + return newItems.size(); + } + + @Override + public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { + DrawerLayoutAdapter.Item oldItem = oldItems.get(oldItemPosition); + DrawerLayoutAdapter.Item newItem = newItems.get(newItemPosition); + + if (oldItem == null || newItem == null) { + return false; + } + + return oldItem.id == newItem.id; + } + + @Override + public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { + DrawerLayoutAdapter.Item oldItem = oldItems.get(oldItemPosition); + DrawerLayoutAdapter.Item newItem = newItems.get(newItemPosition); + + if (oldItem == null || newItem == null) { + return false; + } + + return oldItem.areContentsTheSame(newItem); + } +} \ No newline at end of file