Skip to content

Commit

Permalink
Hide Global/Header Footer when adapter is empty
Browse files Browse the repository at this point in the history
As described in #31 when the adapter is empty, the global header/footer (which are displayed in cells) overlap the empty view.

While the desired behaviour in some cases might be to make the emptyview fill the remaining space that the global header/footer do not occupy, the problem is the header/footer are implemented as cells in the list (so they scroll with the content of the list - if you didn't want them to scroll, you'd put them outside of the list anyway), so it would be challenging to make the empty view a cell which fills the remaining space.

This change instead hides the global header/footer if the adapter is empty, so that the empty view fills the entire space.  If you really want the same global header/footer to appear when the adapter is empty, you can simply add them also to your empty view template (eg: use a grid with `RowDefinitions="Auto,*Auto"` where your header and footer are rows 0 and 2 and the middle view fills the remaining space.
  • Loading branch information
Redth committed Apr 19, 2024
1 parent 75c1bc9 commit fa5dfd0
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
9 changes: 9 additions & 0 deletions Sample/VirtualListViewSample/MusicLibraryPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@
<Label Padding="20" Text="That's all folks!" TextColor="White" HorizontalOptions="Center" />
</Grid>
</vlv:VirtualListView.GlobalFooter>

<vlv:VirtualListView.EmptyView>
<Grid>
<Label
VerticalOptions="Center"
HorizontalOptions="Center"
Text="No Items" />
</Grid>
</vlv:VirtualListView.EmptyView>
</vlv:VirtualListView>

</ContentPage>
7 changes: 6 additions & 1 deletion VirtualListView/Adapters/VirtualListViewAdapterBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

public abstract class VirtualListViewAdapterBase<TSection, TItem> : IVirtualListViewAdapter
{
public virtual int GetNumberOfSections() => 1;
// This adapter assumes we only ever have 1 section
// however we really want to return 0 if there's no items at all
// So, ask the derived class how many items might be in the first
// section and if any, we return 1 section otherwise 0
public virtual int GetNumberOfSections() =>
GetNumberOfItemsInSection(0) > 0 ? 1 : 0;

public event EventHandler OnDataInvalidated;

Expand Down
30 changes: 26 additions & 4 deletions VirtualListView/PositionalViewSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,32 @@ int GetTotalCount()
{
var sum = 0;

if (HasGlobalHeader)
sum += 1;
var hasAtLeastOneItem = false;
var numberOfSections = Adapter.GetNumberOfSections();

if (HasGlobalHeader && numberOfSections > 0)
{
// Make sure that there's at least one section with at least
// one item, otherwise it's 'empty'
// The default adapter may always return 1 for number of sections
// so it's not enough to check that
for (int s = 0; s < numberOfSections; s++)
{
if (Adapter.GetNumberOfItemsInSection(s) > 0)
{
sum += 1;
// If we found one, we can stop looping
// since we just care to calculate a spot
// for the header cell if the adapter isn't empty
hasAtLeastOneItem = true;
break;
}
}
}

if (Adapter != null)
{
for (int s = 0; s < Adapter.GetNumberOfSections(); s++)
for (int s = 0; s < numberOfSections; s++)
{
if (ViewSelector.SectionHasHeader(s))
sum += 1;
Expand All @@ -45,7 +65,9 @@ int GetTotalCount()
}
}

if (HasGlobalFooter)
// Only count footer if there is already at least one item
// otherwise the adapter is empty and we shouldn't count it
if (HasGlobalFooter && hasAtLeastOneItem)
sum += 1;

return sum;
Expand Down

0 comments on commit fa5dfd0

Please sign in to comment.