Sie sollten FooterTemplate und Footer-Eigenschaften verwenden. Es funktioniert als ItemTemplate und ItemSource:
<ListView Footer="{Binding IsFooterVisible}">
<ListView.FooterTemplate>
<DataTemplate>
<!-- Footer content. Always visible -->
</DataTemplate>
<ListView.FooterTemplate>
</ListView>
Und binden an Footer-Eigenschaft etwas Nullable (Objekt zum Beispiel). Oder Sie konvertieren Converter: true -> new object() und false -> null
Es ist auch möglich, eine Unterklasse von ListView zu erstellen. Mein Beispiel (IsLoading Eigenschaft ist das, was Sie suchen):
XAML:
<?xml version="1.0" encoding="UTF-8"?>
<ListView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Panor.Views.LoadableListView"
x:Name="element"
>
<ListView.FooterTemplate>
<DataTemplate>
<ContentView>
<ActivityIndicator IsRunning="true"
Margin="0, 5"
Color="{StaticResource mainColor}"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
>
<ActivityIndicator.Scale>
<OnPlatform x:TypeArguments="x:Double" iOS="2" Android="1" />
</ActivityIndicator.Scale>
</ActivityIndicator>
</ContentView>
</DataTemplate>
</ListView.FooterTemplate>
</ListView>
-Code-behind:
public partial class LoadableListView : ListView
{
public LoadableListView()
{
InitializeComponent();
this.ItemAppearing += OnItemAppearing;
}
public static readonly BindableProperty IsLoadingProperty = BindableProperty.Create(
nameof(IsLoading),
typeof(bool),
typeof(LoadableListView),
false,
propertyChanged: (bindable, oldValue, newValue) =>
{
var element = (LoadableListView)bindable;
element.Footer = (bool)newValue ? new object() : null;
}
);
public bool IsLoading
{
set => SetValue(IsLoadingProperty, value);
get => (bool)GetValue(IsLoadingProperty);
}
public static readonly BindableProperty ScrolledDownCommandProperty = BindableProperty.Create(
nameof(ScrolledDownCommand),
typeof(ICommand),
typeof(LoadableListView)
);
public ICommand ScrolledDownCommand
{
set => SetValue(ScrolledDownCommandProperty, value);
get => (ICommand)GetValue(ScrolledDownCommandProperty);
}
void OnItemAppearing(object sender, ItemVisibilityEventArgs e)
{
if (ItemsSource == null) return;
if (ScrolledDownCommand == null) return;
object last = null;
if (ItemsSource is IList)
{
var length = (ItemsSource as IList).Count;
last = (ItemsSource as IList)[length - 1];
}
else
{
foreach (var item in ItemsSource)
last = item;
}
if (e.Item == last && ScrolledDownCommand.CanExecute(null))
ScrolledDownCommand.Execute(null);
}
Konsumieren:
<views:LoadableListView ItemsSource="{Binding ItemSource}"
RowHeight="120"
SeparatorColor="#c7c8c9"
IsLoading="{Binding IsMoreLoading}"
ScrolledDownCommand="{Binding ScrolledDownCommand}"
IsPullToRefreshEnabled="true"
IsRefreshing="{Binding IsRefreshing}"
RefreshCommand="{Binding RefreshCommand}"
>
<views:LoadableListView.ItemTemplate>
<DataTemplate>
<cells:MagazinesListCell Name="{Binding Name}"
Publisher="{Binding Publisher}"
Price="{Binding Price}"
Image="{Binding Converter={StaticResource UriToImageSourceConvertor}, Path=Image}"
Commands="{Binding Commands}"
/>
</DataTemplate>
</views:LoadableListView.ItemTemplate>
</views:LoadableListView>
Ich habe HeightRequest zuvor versucht, aber es tut es nicht Arbeit. Die Fußzeile ignoriert sie und verbraucht immer noch diesen Speicherplatz, selbst wenn ForceLayout auf dem übergeordneten ContentView ausgelöst wird. – Florian
Arbeiten Sie mit iOS, Android oder etwas anderem? Ich habe gerade einen kurzen Test mit diesem Code auf Android durchgeführt, der die 'FooterIsVisible' ein- und ausschaltet und es scheint so weit zu funktionieren, wie ich das Problem verstehe. Ich habe im Moment keinen Zugriff auf meinen Mac, also kann ich es nicht auf iOS anschauen. –
Vielen Dank für die Überprüfung. Ich habe es erneut auf iOS und Android versucht und du bist richtig für Android. Da funktioniert es, das Problem besteht also nur auf iOS. Sobald die Fußzeile sichtbar ist, bleibt sie übrig, um den gleichen Platz zu verbrauchen, selbst wenn sie unsichtbar ist. Das könnte ein Fehler sein. Ich habe den Eindruck, dass Xamarin nicht wirklich auf "kleinere" Probleme reagiert - also muss ich wohl damit leben. – Florian