From f7393eba91510efcc1f0e3b222af091fa526df0e Mon Sep 17 00:00:00 2001 From: GarikCarrot Date: Fri, 21 Aug 2020 06:32:02 +0300 Subject: [PATCH 1/4] Use DiffUils in header and footer (Section) --- .../java/com/xwray/groupie/DiffCallback.java | 6 ++ .../main/java/com/xwray/groupie/Section.java | 97 +++++++++++++------ 2 files changed, 75 insertions(+), 28 deletions(-) diff --git a/library/src/main/java/com/xwray/groupie/DiffCallback.java b/library/src/main/java/com/xwray/groupie/DiffCallback.java index 88188cb4..a1977c79 100644 --- a/library/src/main/java/com/xwray/groupie/DiffCallback.java +++ b/library/src/main/java/com/xwray/groupie/DiffCallback.java @@ -1,9 +1,11 @@ package com.xwray.groupie; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.DiffUtil; import java.util.Collection; +import java.util.Collections; class DiffCallback extends DiffUtil.Callback { private final int oldBodyItemCount; @@ -11,6 +13,10 @@ class DiffCallback extends DiffUtil.Callback { private final Collection oldGroups; private final Collection newGroups; + DiffCallback(@NonNull Group oldGroup, @NonNull Group newGroup) { + this(Collections.singletonList(oldGroup), Collections.singletonList(newGroup)); + } + DiffCallback(Collection oldGroups, Collection newGroups) { this.oldBodyItemCount = GroupUtils.getItemCount(oldGroups); this.newBodyItemCount = GroupUtils.getItemCount(newGroups); diff --git a/library/src/main/java/com/xwray/groupie/Section.java b/library/src/main/java/com/xwray/groupie/Section.java index 6725afb3..07d91c0a 100644 --- a/library/src/main/java/com/xwray/groupie/Section.java +++ b/library/src/main/java/com/xwray/groupie/Section.java @@ -119,6 +119,7 @@ public void removeAll(@NonNull Collection groups) { /** * Get the list of all groups in this section, wrapped in a new {@link ArrayList}. This * does not include headers, footers or placeholders. + * * @return The list of all groups in this section, wrapped in a new {@link ArrayList} */ public List getGroups() { @@ -145,11 +146,11 @@ public void clear() { *

* If you don't customize getId() or isSameAs() and hasSameContentAs(), the default implementations will return false, * meaning your Group will consider every update a complete change of everything. - * + *

* This will default detectMoves to true. * - * @see #update(Collection, boolean) * @param newBodyGroups The new content of the section + * @see #update(Collection, boolean) */ public void update(@NonNull final Collection newBodyGroups) { update(newBodyGroups, true); @@ -167,8 +168,8 @@ public void update(@NonNull final Collection newBodyGroups) { * meaning your Group will consider every update a complete change of everything. * * @param newBodyGroups The new content of the section - * @param detectMoves is passed to {@link DiffUtil#calculateDiff(DiffUtil.Callback, boolean)}. Set to false if you - * don't want DiffUtil to detect moved items. + * @param detectMoves is passed to {@link DiffUtil#calculateDiff(DiffUtil.Callback, boolean)}. Set to false if you + * don't want DiffUtil to detect moved items. */ public void update(@NonNull final Collection newBodyGroups, boolean detectMoves) { final List oldBodyGroups = new ArrayList<>(children); @@ -178,6 +179,7 @@ public void update(@NonNull final Collection newBodyGroups, boo /** * Overloaded version of update method in which you can pass your own DiffUtil.DiffResult + * * @param newBodyGroups The new content of the section * @param diffResult */ @@ -378,15 +380,17 @@ private boolean isPlaceholderShown() { } public void setHeader(@NonNull Group header) { + //noinspection ConstantConditions if (header == null) throw new NullPointerException("Header can't be null. Please use removeHeader() instead!"); if (this.header != null) { this.header.unregisterGroupDataObserver(this); } - int previousHeaderItemCount = getHeaderItemCount(); + + Group previousHeader = this.header; this.header = header; header.registerGroupDataObserver(this); - notifyHeaderItemsChanged(previousHeaderItemCount); + notifyHeaderItemsChanged(previousHeader, header); } public void removeHeader() { @@ -394,33 +398,31 @@ public void removeHeader() { return; } + Group header = this.header; this.header.unregisterGroupDataObserver(this); - int previousHeaderItemCount = getHeaderItemCount(); this.header = null; - notifyHeaderItemsChanged(previousHeaderItemCount); + notifyHeaderItemsChanged(header, null); } - private void notifyHeaderItemsChanged(int previousHeaderItemCount) { - int newHeaderItemCount = getHeaderItemCount(); - if (previousHeaderItemCount > 0) { - notifyItemRangeRemoved(0, previousHeaderItemCount); - } - if (newHeaderItemCount > 0) { - notifyItemRangeInserted(0, newHeaderItemCount); - } + private void notifyHeaderItemsChanged( + @Nullable final Group previousHeader, + @Nullable final Group newHeader + ) { + notifyHeaderOrFooterChanged(0, previousHeader, newHeader); } - public void setFooter(@NonNull Group footer) { + //noinspection ConstantConditions if (footer == null) throw new NullPointerException("Footer can't be null. Please use removeFooter() instead!"); if (this.footer != null) { this.footer.unregisterGroupDataObserver(this); } - int previousFooterItemCount = getFooterItemCount(); + + Group previousFooter = this.footer; this.footer = footer; footer.registerGroupDataObserver(this); - notifyFooterItemsChanged(previousFooterItemCount); + notifyFooterItemsChanged(previousFooter, footer); } public void removeFooter() { @@ -428,20 +430,59 @@ public void removeFooter() { return; } + Group previousFooter = this.footer; this.footer.unregisterGroupDataObserver(this); - int previousFooterItemCount = getFooterItemCount(); this.footer = null; - notifyFooterItemsChanged(previousFooterItemCount); + notifyFooterItemsChanged(previousFooter, null); } - private void notifyFooterItemsChanged(int previousFooterItemCount) { - int newFooterItemCount = getFooterItemCount(); - if (previousFooterItemCount > 0) { - notifyItemRangeRemoved(getItemCountWithoutFooter(), previousFooterItemCount); - } - if (newFooterItemCount > 0) { - notifyItemRangeInserted(getItemCountWithoutFooter(), newFooterItemCount); + private void notifyFooterItemsChanged( + @Nullable Group previousFooter, + @Nullable Group newFooter + ) { + notifyHeaderOrFooterChanged(getItemCountWithoutFooter(), previousFooter, newFooter); + } + + private void notifyHeaderOrFooterChanged( + final int positionStart, + @Nullable final Group prevGroup, + @Nullable final Group newGroup + ) { + final int previousHeaderItemCount = prevGroup == null ? 0 : prevGroup.getItemCount(); + final int newHeaderItemCount = newGroup == null ? 0 : newGroup.getItemCount(); + + if (previousHeaderItemCount == 0 && newHeaderItemCount == 0) return; + if (previousHeaderItemCount == 0) { + notifyItemRangeInserted(positionStart, newHeaderItemCount); + return; + } else if (newHeaderItemCount == 0) { + notifyItemRangeRemoved(positionStart, previousHeaderItemCount); + return; } + + DiffUtil.Callback callback = new DiffCallback(prevGroup, newGroup); + DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(callback, true); + diffResult.dispatchUpdatesTo(new ListUpdateCallback() { + @Override + public void onInserted(int position, int count) { + notifyItemRangeChanged(position + positionStart, count); + } + + @Override + public void onRemoved(int position, int count) { + notifyItemRangeRemoved(position + positionStart, count); + } + + @Override + public void onMoved(int fromPosition, int toPosition) { + notifyItemMoved(fromPosition + positionStart, toPosition + positionStart); + } + + @Override + public void onChanged(int position, int count, @Nullable Object payload) { + notifyItemRangeChanged(position + positionStart, count, payload); + } + }); } public void setHideWhenEmpty(boolean hide) { From 73c6dd7d6511b34a94aece496b70f2bd9e2d2a13 Mon Sep 17 00:00:00 2001 From: GarikCarrot Date: Fri, 21 Aug 2020 07:52:51 +0300 Subject: [PATCH 2/4] Revert useless changes --- library/src/main/java/com/xwray/groupie/Section.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/library/src/main/java/com/xwray/groupie/Section.java b/library/src/main/java/com/xwray/groupie/Section.java index 07d91c0a..41074a10 100644 --- a/library/src/main/java/com/xwray/groupie/Section.java +++ b/library/src/main/java/com/xwray/groupie/Section.java @@ -119,7 +119,6 @@ public void removeAll(@NonNull Collection groups) { /** * Get the list of all groups in this section, wrapped in a new {@link ArrayList}. This * does not include headers, footers or placeholders. - * * @return The list of all groups in this section, wrapped in a new {@link ArrayList} */ public List getGroups() { @@ -146,7 +145,7 @@ public void clear() { *

* If you don't customize getId() or isSameAs() and hasSameContentAs(), the default implementations will return false, * meaning your Group will consider every update a complete change of everything. - *

+ * * This will default detectMoves to true. * * @param newBodyGroups The new content of the section @@ -168,8 +167,8 @@ public void update(@NonNull final Collection newBodyGroups) { * meaning your Group will consider every update a complete change of everything. * * @param newBodyGroups The new content of the section - * @param detectMoves is passed to {@link DiffUtil#calculateDiff(DiffUtil.Callback, boolean)}. Set to false if you - * don't want DiffUtil to detect moved items. + * @param detectMoves is passed to {@link DiffUtil#calculateDiff(DiffUtil.Callback, boolean)}. Set to false if you + * don't want DiffUtil to detect moved items. */ public void update(@NonNull final Collection newBodyGroups, boolean detectMoves) { final List oldBodyGroups = new ArrayList<>(children); @@ -179,7 +178,6 @@ public void update(@NonNull final Collection newBodyGroups, boo /** * Overloaded version of update method in which you can pass your own DiffUtil.DiffResult - * * @param newBodyGroups The new content of the section * @param diffResult */ From 29feecebca473c25f7bf78b48063107fc23045fe Mon Sep 17 00:00:00 2001 From: GarikCarrot Date: Fri, 21 Aug 2020 07:54:48 +0300 Subject: [PATCH 3/4] Revert useless changes --- library/src/main/java/com/xwray/groupie/Section.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/main/java/com/xwray/groupie/Section.java b/library/src/main/java/com/xwray/groupie/Section.java index 41074a10..b66a9402 100644 --- a/library/src/main/java/com/xwray/groupie/Section.java +++ b/library/src/main/java/com/xwray/groupie/Section.java @@ -148,8 +148,8 @@ public void clear() { * * This will default detectMoves to true. * - * @param newBodyGroups The new content of the section * @see #update(Collection, boolean) + * @param newBodyGroups The new content of the section */ public void update(@NonNull final Collection newBodyGroups) { update(newBodyGroups, true); From 2ca5cbcf6cdec04de9a485fb2dd4e8a31b382cb8 Mon Sep 17 00:00:00 2001 From: GarikCarrot Date: Fri, 21 Aug 2020 08:16:06 +0300 Subject: [PATCH 4/4] Fix insert --- library/src/main/java/com/xwray/groupie/Section.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/main/java/com/xwray/groupie/Section.java b/library/src/main/java/com/xwray/groupie/Section.java index b66a9402..575bf7ce 100644 --- a/library/src/main/java/com/xwray/groupie/Section.java +++ b/library/src/main/java/com/xwray/groupie/Section.java @@ -463,7 +463,7 @@ private void notifyHeaderOrFooterChanged( diffResult.dispatchUpdatesTo(new ListUpdateCallback() { @Override public void onInserted(int position, int count) { - notifyItemRangeChanged(position + positionStart, count); + notifyItemRangeInserted(position + positionStart, count); } @Override