Worked it out, was able to detect top item using ItemAppearing and ItemDisappearing.
Xamarin Forms ListView get first visible item
Hi,
How can I detect first visible item in ListView? I've tried using ItemAppearing and ItemDisappearing events, but ItemDisappearing returns unreliable results e.g. tells that item disappeared, but that item was not even visible etc.
Is there any other way to detect when top visible item changes?
Cheers.
2 answers
Sort by: Most helpful
-
-
Leon Lu (Shanghai Wicresoft Co,.Ltd.) 72,336 Reputation points Microsoft Vendor
2021-12-10T06:08:21.817+00:00 Hello,
Welcome to our Microsoft Q&A platform!
I compare first item's height and the
e.ScrollY
's value from thelistView_Scrolled
event. If thee.ScrollY
's valueis bigger than item's height, the first item is disappear. If the item is appearing, we can detect it in the
ViewCell_Appearingor
ItemAppearing` method.Here is my layout.
<ListView x:Name="listView" ItemsSource="{Binding Employees}" Scrolled="listView_Scrolled" > <ListView.ItemTemplate> <DataTemplate> <!-- Disappearing="ViewCell_Disappearing" --> <ViewCell Appearing="ViewCell_Appearing" > <StackLayout SizeChanged="StackLayout_SizeChanged"> <Label Text="{Binding Id}"></Label> <Label Text="{Binding DisplayName}"></Label> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView>
Here is my background code.
public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); BindingContext = new MyViewDodel(); } bool isShowing = false; StackLayout sl; private void ViewCell_Appearing(object sender, EventArgs e) { if (sender != null) { ViewCell viewCell = sender as ViewCell; sl = viewCell.View as StackLayout; Label label = sl.Children[0] as Label; if (label.Text == "1") { isShowing = true; DisplayAlert("info", "first item appearing", "OK"); } } } private void listView_Scrolled(object sender, ScrolledEventArgs e) { if (sl != null) { double value = itemsHeight[sl.Id]; if (isShowing) { if (e.ScrollY > value) { isShowing = false; DisplayAlert("info", "first item disappearing", "OK"); } } } } private Dictionary<Guid, double> itemsHeight = new Dictionary<Guid, double>(); private void StackLayout_SizeChanged(object sender, EventArgs e) { StackLayout stackLayout = (StackLayout)sender; if (!itemsHeight.ContainsKey(stackLayout.Id)) itemsHeight.Add(stackLayout.Id, stackLayout.Height); else itemsHeight[stackLayout.Id] = stackLayout.Height; listView.HeightRequest = itemsHeight.Sum(x => x.Value); } }
Best Regards,
Leon Lu
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.