[Android] CollectionView Header/Footer/EmptyView issues when adding/removing items. #24830
+20
−17
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Sub-Issue1: The footer is not always shown, it appears only for one in two added items
Root Cause
In the AdapterNotifier class, the NotifyItemRangeChanged calls in the NotifyItemInserted and NotifyItemRemoved methods incorrectly used the total _adapter.ItemCount, which included the footer element. This caused the footer to be treated as part of the updated range, leading to the footer being hidden when an odd number of items were added to the CollectionView. When an even number of items were added, the footer reappeared due to the adjusted range calculation.
Description of Change
The fix involved removing unnecessary NotifyItemRangeChanged function calls from the NotifyItemInserted, NotifyItemRemoved, NotifyItemMoved, and NotifyItemRangeInserted methods, as they caused incorrect updates to the footer visibility. These changes were made based on the reference from the Xamarin source code (https://github.com/xamarin/Xamarin.Forms/pull/15236/files#diff-45f23f6731e03254ee2692d1f9d79a864fc85fa802e7fc90eb64656a02156c12), ensuring that the CollectionView properly handles the visibility of the footer during item insertions and removals without the need for redundant range updates.
Fix done at AdapterNotifier.cs
Sub-Issue2: when the last item is removed from the source, the header becomes blank and the footer moves to the bottom of the page
Root Cause
In the MauiRecyclerView class, when dynamically switching between an empty view and item view, or vice versa, the adapter's recycled view pool was not cleared. This caused view type mismatches in the recycled view pool, leading to the incorrect rendering of header and footer views. When transitioning from an empty view to an item view, or vice versa, the header and footer views were missing due to the recycled view holders not being correctly updated for the new adapter.
Description of Change
The fix involved clearing the RecyclerView's recycled view pool before swapping adapters using
GetRecycledViewPool().Clear()
. This ensures that when switching between an empty view and item view, the recycled views (header and footer) are properly recreated with the correct view holders. This change resolved the issue of header and footer views not rendering correctly when transitioning between an empty and item view dynamically.Fix done at MauiRecyclerView.cs
Sub-Issue3: The footer is not always shown, it appears only for one in two added items
Root Cause
The issue occurred when using HeaderTemplate and FooterTemplate in a CollectionView. The footer template was not rendered after switching from an empty view to an item view. This was because the empty view incorrectly occupied the entire available space, preventing the footer from being displayed. The incorrect behavior stemmed from the UpdateEmptyViewSize method, which did not properly measure and adjust the size of the empty view, especially when using templates. The footer template was never created because the RecyclerView did not allocate space for it due to the wrong measurement of the empty view.
Description of Change
The fix involved updating the UpdateEmptyViewSize method to accurately measure the height of the empty view, whether it was a direct IView or a DataTemplate. By ensuring the correct height was set for the RecyclerView, we allowed the footer template to be rendered correctly. This change ensures that the empty view does not take up the entire available space, and the footer can appear as expected when transitioning between item views and empty views.
Fix done at Items/ItemsViewHandler.Android.cs
Issues Fixed
Fixes #11896
Validated the behaviour in the following platforms
Screenshots
Before:
After: