I have 3 tabs on the top of the page where I am listing some data using ListView
. When I tap on a tab I need to scroll to the end of the listview, I mean I need to scroll to the last item of the ListView
. I am reversing the collection before setting it to the ListView
. I used below codes to scroll to last item:
settingslistview.ScrollTo(tab1settingList[tab1settingList.Count - 1], ScrollToPosition.End, false);
This is working fine if we not reverse the data. But when reversing the scrolling is not working.
I am adding the sample codes of my demo project below:
MainPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ScrollToDemo.MainPage">
<StackLayout>
<Grid
Margin="10,0,10,0"
VerticalOptions="StartAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="33*" />
<ColumnDefinition Width="34*" />
<ColumnDefinition Width="33*" />
</Grid.ColumnDefinitions>
<StackLayout
Grid.Column="0"
HorizontalOptions="FillAndExpand"
Margin="2,0"
VerticalOptions="FillAndExpand"
Orientation="Vertical">
<Label
x:Name="tab1_label"
FontAttributes="Bold"
Text="Tab1"
Style="{StaticResource style1}"/>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
Tapped="Tab1Tapped"
NumberOfTapsRequired="1">
</TapGestureRecognizer>
</StackLayout.GestureRecognizers>
</StackLayout>
<StackLayout
Grid.Column="1"
HorizontalOptions="FillAndExpand"
Margin="2,0"
VerticalOptions="FillAndExpand"
Orientation="Vertical">
<Label
x:Name="tab2_label"
IsEnabled="False"
Text="Tab2"
Style="{StaticResource style1}"/>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
Tapped="Tab2Tapped"
NumberOfTapsRequired="1">
</TapGestureRecognizer>
</StackLayout.GestureRecognizers>
</StackLayout>
<StackLayout
Grid.Column="2"
HorizontalOptions="FillAndExpand"
Margin="2,0"
VerticalOptions="FillAndExpand"
Orientation="Vertical">
<Label
x:Name="tab3_label"
IsEnabled="False"
Text="Tab3"
Style="{StaticResource style1}"/>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
Tapped="Tab3Tapped"
NumberOfTapsRequired="1">
</TapGestureRecognizer>
</StackLayout.GestureRecognizers>
</StackLayout>
</Grid>
<ListView
x:Name="settingslistview"
HasUnevenRows="True"
SelectionMode="None"
SeparatorColor="#cecece"
SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Frame
HasShadow="False"
Padding="8"
CornerRadius="{OnIdiom Phone=20, Tablet=30}"
BorderColor="#bdbdbd"
Margin="5"
BackgroundColor="{Binding BGColor}">
<StackLayout
VerticalOptions="FillAndExpand"
Margin="5,0,5,0"
Orientation="Horizontal">
<Label
Text="{Binding Title}"
HorizontalOptions="StartAndExpand"
VerticalOptions="CenterAndExpand"
TextColor="{Binding TextColor}">
<Label.FontSize>
<OnIdiom x:TypeArguments="x:Double">
<OnIdiom.Phone>18</OnIdiom.Phone>
<OnIdiom.Tablet>27</OnIdiom.Tablet>
<OnIdiom.Desktop>18</OnIdiom.Desktop>
</OnIdiom>
</Label.FontSize>
</Label>
</StackLayout>
<Frame.HeightRequest>
<OnIdiom x:TypeArguments="x:Double">
<OnIdiom.Phone>30</OnIdiom.Phone>
<OnIdiom.Tablet>45</OnIdiom.Tablet>
<OnIdiom.Desktop>30</OnIdiom.Desktop>
</OnIdiom>
</Frame.HeightRequest>
</Frame>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Footer>
<Label/>
</ListView.Footer>
</ListView>
</StackLayout>
</ContentPage>
MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace ScrollToDemo
{
public partial class MainPage : ContentPage
{
public ObservableCollection<SettingPageItems> tab1settingList;
public ObservableCollection<SettingPageItems> tab2settingList;
public ObservableCollection<SettingPageItems> tab3settingList;
public MainPage()
{
InitializeComponent();
tab1settingList = new ObservableCollection<SettingPageItems>();
tab2settingList = new ObservableCollection<SettingPageItems>();
tab3settingList = new ObservableCollection<SettingPageItems>();
Tab1Items();
Tab2Items();
Tab3Items();
}
private void Tab1Tapped(object sender, EventArgs e)
{
tab1_label.FontAttributes = FontAttributes.Bold;
tab2_label.FontAttributes = FontAttributes.None;
tab3_label.FontAttributes = FontAttributes.None;
settingslistview.ItemsSource = tab1settingList.Reverse();
if (tab1settingList.Count != 0)
{
Device.BeginInvokeOnMainThread(() =>
{
settingslistview.ScrollTo(tab1settingList[tab1settingList.Count - 1], ScrollToPosition.End, false);
});
}
}
private void Tab2Tapped(object sender, EventArgs e)
{
tab1_label.FontAttributes = FontAttributes.None;
tab2_label.FontAttributes = FontAttributes.Bold;
tab3_label.FontAttributes = FontAttributes.None;
settingslistview.ItemsSource = tab2settingList.Reverse();
if (tab2settingList.Count != 0)
{
Device.BeginInvokeOnMainThread(() =>
{
settingslistview.ScrollTo(tab2settingList[tab2settingList.Count - 1], ScrollToPosition.End, false);
});
}
}
private void Tab3Tapped(object sender, EventArgs e)
{
tab1_label.FontAttributes = FontAttributes.None;
tab2_label.FontAttributes = FontAttributes.None;
tab3_label.FontAttributes = FontAttributes.Bold;
settingslistview.ItemsSource = tab3settingList.Reverse();
if (tab3settingList.Count != 0)
{
Device.BeginInvokeOnMainThread(() =>
{
settingslistview.ScrollTo(tab3settingList[tab3settingList.Count - 1], ScrollToPosition.End, false);
});
}
}
public void Tab1Items()
{
for(int i =1; i<= 20; i++)
{
tab1settingList.Add(new SettingPageItems() { Title = "Option"+i, BGColor = Color.FromHex("#e4e4e4"), TextColor = Color.Black });
}
settingslistview.ItemsSource = tab1settingList.Reverse();
}
public void Tab2Items()
{
for (int i = 21; i <= 40; i++)
{
tab2settingList.Add(new SettingPageItems() { Title = "Option" + i, BGColor = Color.FromHex("#FFEBEE"), TextColor = Color.Black });
}
}
public void Tab3Items()
{
for (int i = 41; i <= 60; i++)
{
tab3settingList.Add(new SettingPageItems() { Title = "Option" + i, BGColor = Color.FromHex("#E8EAF6"), TextColor = Color.Black });
}
}
}
}
public class SettingPageItems : INotifyPropertyChanged
{
public string Title { get; set; }
private Color bgColor;
public Color BGColor
{
set
{
if (value != null)
{
bgColor = value;
NotifyPropertyChanged();
}
}
get
{
return bgColor;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private Color textColor;
public Color TextColor
{
set
{
if (value != null)
{
textColor = value;
NotifyPropertyChanged();
}
}
get
{
return textColor;
}
}
private string imageSource;
public string ImageSource
{
set
{
if (value != null)
{
imageSource = value;
NotifyPropertyChanged();
}
}
get
{
return imageSource;
}
}
}
App.xaml
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ScrollToDemo.App">
<Application.Resources>
<Style x:Key="style1" TargetType="Label">
<Setter Property="HorizontalTextAlignment" Value="Center"/>
<Setter Property="HorizontalOptions" Value="CenterAndExpand"/>
<Setter Property="VerticalTextAlignment" Value="Center"/>
<Setter Property="TextColor" Value="Black" />
<Setter Property="FontSize">
<OnIdiom
x:TypeArguments="x:Double"
Phone="18"
Tablet="27"
Desktop="18"/>
</Setter>
</Style>
</Application.Resources>
</Application>
I have uploaded a sample demo here. I need to scroll to the last item of the listview when switching to other tabs. Currently it is on top of the page when switching.