Articles in this section
Category / Section

How to bring the entire item into view on tapping an item in xamarin.forms expandable listview?

3 mins read

You can bring an item into view by calling ScrollToRowIndex method. This article explains how to create expandable listview and how to bring the listview item into view when its being expanded.

In the below code, ItemTemplate of ListView is defined to show or hide additional view based on IsVisible property in Model class (namely Contact).

Xaml

 
<ContentPage xmlns:sflistview="clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms">
  <ContentPage.Content>
    <Grid x:Name="mainGrid">
      <sflistview:SfListView x:Name="listView" AutoFitMode="DynamicHeight">
        < sflistview:SfListView.Behaviors>
            <local:SfListViewAccordionBehavior />
        </ sflistview:SfListView.Behaviors>
        <sflistview:SfListView.ItemTemplate>
          <DataTemplate>
            <ViewCell>
                <Grid >
                  <Frame x:Name="frame">
                    <Grid>
                      <Grid x:Name="grid">
                        <Grid.RowDefinitions>
                              <RowDefinition Height="60" />
                        </Grid.RowDefinitions>
                        <Grid RowSpacing="0">
                          <Grid.ColumnDefinitions>
                               <ColumnDefinition Width="60" />
                               <ColumnDefinition Width="*" />
                               <ColumnDefinition Width="50" />
                               </Grid.ColumnDefinitions>
                          <Image Grid.Row="0" Grid.Column="0" Source="{Binding ContactImage}" />
                          <Grid Grid.Row="0" Grid.Column="1" >
                            <Grid.RowDefinitions>
                              <RowDefinition Height="*" />
                              <RowDefinition Height="*" />
                            </Grid.RowDefinitions>
                            <Label Grid.Row="0" Text="{Binding ContactName}">
                            </Label>
                            <Label Grid.Row="1" Text="{Binding CallTime}">
                            </Label>
                          </Grid>
                          <Grid Grid.Row="0" Grid.Column="2" >
                            <Image Source="{Binding PhoneImage}" />
                          </Grid>
                        </Grid>
                      </Grid>
                      <Grid IsVisible="{Binding IsVisible, Mode=TwoWay}">
                        <Grid.RowDefinitions>
                          <RowDefinition Height="1" />
                          <RowDefinition Height="40" />
                          <RowDefinition Height="40" />
                          <RowDefinition Height="40" />
                          <RowDefinition Height="40" />
                          <RowDefinition Height="40" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions >
                          <ColumnDefinition Width="50" />
                          <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <BoxView Grid.Row="0" Grid.Column="0"/>
                        <Image Grid.Row="1" Grid.Column="0" Source="{Binding NewContact}" />
                        <Image Grid.Row="2" Grid.Column="0" Source="{Binding AddContact}" />
                        <Image Grid.Row="3" Grid.Column="0" Source="{Binding SendMessage}" />
                        <Image Grid.Row="4" Grid.Column="0" Source="{Binding BlockSpan}" />
                        <Image Grid.Row="5" Grid.Column="0" Source="{Binding CallDetails}"/>
                        <BoxView Grid.Row="0" Grid.Column="1"/>
                        <Label Grid.Row="1" Grid.Column="1" Text="Create new contact"/>
                        <Label Grid.Row="2" Grid.Column="1" Text="Add to a contact"/>
                        <Label Grid.Row="3" Grid.Column="1" Text="Send a message"/>
                        <Label Grid.Row="4" Grid.Column="1" Text="Block/report Spam"/>
                        <Label Grid.Row="5" Grid.Column="1" Text="Call details"/>
                      </Grid>
                    </Grid>
                  </Frame>
                </Grid>
              </ViewCell.View>
            </ViewCell>
          </DataTemplate>
        </sflistview:SfListView.ItemTemplate>
      </sflistview:SfListView>
    </Grid>
  </ContentPage.Content>
</ContentPage>
 

 

Also, code added to change the IsVisible when listview item is tapped. Now expandable listview is ready.

C#

 
namespace AutoFit
{
    internal class SfListViewAccordionBehavior : Behavior<SfListView>
    {
        public SfListViewAccordionBehavior()
        {
            AccordionViewModel = new AccordionViewModel();
        }
 
       protected override void OnAttachedTo(ContentPage bindable)
        {
            listview = bindable.FindByName<Syncfusion.ListView.XForms.SfListView>("listView");
            listview.ItemsSource = AccordionViewModel.ContactsInfo;
            listview.ItemTapped += ListView_ItemTapped;
        }
        
        private void ListView_ItemTapped(object sender, Syncfusion.ListView.XForms.ItemTappedEventArgs e)
        {
            if (tappedItem != null && tappedItem.IsVisible)
            {
                tappedItem.IsVisible = false;
            }
 
            if (tappedItem == ItemData )
            {
                tappedItem = null;
                return;
            }
 
            tappedItem = ItemData;
            tappedItem.IsVisible = true;
        }    
    }
}
 

 

Now, you can call ScrollToRowIndex method when an item is tapped and bring that item into view if it is not fully visible.

C#

 
namespace AutoFit
{
    internal class SfListViewAccordionBehavior : Behavior<SfListView>
    {      
        protected override void OnAttachedTo(ContentPage bindable)
        {
            listview = bindable.FindByName<Syncfusion.ListView.XForms.SfListView>("listView");
            listview.ItemsSource = AccordionViewModel.ContactsInfo;
            listview.ItemTapped += ListView_ItemTapped;
        }
        
        private void ListView_ItemTapped(object sender, Syncfusion.ListView.XForms.ItemTappedEventArgs e)
        {
       visibleLines = this.listview.GetVisualContainer().ScrollRows.GetVisibleLines();
            
           var tappedItemIndex = listview.DataSource.DisplayItems.IndexOf(e.ItemData as Contact);
 
            if (visibleLines.Count <= 0)
                return;
 
            var endIndex = visibleLines[visibleLines.LastBodyVisibleIndex].LineIndex;
            if (tappedItemIndex == endIndex) 
            {
                Device.BeginInvokeOnMainThread(async () =>
                {
                    await Task.Delay(200);
                    (listview.LayoutManager as LinearLayout).ScrollToRowIndex(tappedItemIndex, Syncfusion.ListView.XForms.ScrollToPosition.End, true);
                });
            }
        }
    }
}
 

 

Screenshot

Download sample from GitHub

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please  to leave a comment
Access denied
Access denied