Xamarin Forms ListView get first visible item

EJ 366 Reputation points
2021-12-10T00:36:27.18+00:00

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.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,254 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. EJ 366 Reputation points
    2021-12-10T03:00:41.117+00:00

    Worked it out, was able to detect top item using ItemAppearing and ItemDisappearing.


  2. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 63,921 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 the listView_Scrolled event. If the e.ScrollY's valueis bigger than item's height, the first item is disappear. If the item is appearing, we can detect it in theViewCell_AppearingorItemAppearing` 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.