Hello,
This issue can be fixed by using Display grouped data in a CollectionView - .NET MAUI | Microsoft Learn to replace of the following code in the NearBusStopsView.xaml
. You used to many nested StackLayout indableLayout.ItemsSource
. and Nested ContentView. When you load to many data at once, you will get performance issue. You will see [xxx.ap] Explicit concurrent copying GC freed 1730(73KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 5533KB/10MB, paused 264us,61us total 15.069ms
in the output window, when you debug your application.
<ScrollView VerticalScrollBarVisibility="Never">
<VerticalStackLayout Margin="0,15,0,0"
Spacing="16"
BackgroundColor="Transparent"
BindableLayout.ItemsSource="{Binding PublicTransportStops}">
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="models:PublicTransportStop">
<cts:PublicTransportStopItem />
</DataTemplate>
</BindableLayout.ItemTemplate>
</VerticalStackLayout>
</ScrollView>
Before changing the code, you can comment-line above code, this performance issue will be fixed.
Firstly, I change PublicTransportStop.cs
code like above document. By the way, we cannot extend multiply classes in C#, So I use INotifyPropertyChanged to instead of the INotifyPropertyChanged
.
public partial class PublicTransportStop : List<PublicTransport>, INotifyPropertyChanged
{
public PublicTransportStop(List<PublicTransport> publicTransports) : base(publicTransports)
{
StopDescription = string.Empty;
}
public string StopNumber { get; set; }
public string StopDescription { get; set; }
private bool isStared;
public bool IsStared
{
get { return isStared; }
set { isStared = value; OnPropertyChanged(); }
}
public int Distance { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string name = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
Then you need to change popup data way in the GetNearestBusStopsAsync
of GttTransportService.cs
public Task<List<PublicTransportStop>> GetNearestBusStopsAsync(int distance)
{
return Task.FromResult(new List<PublicTransportStop>()
{
new PublicTransportStop(new List<PublicTransport>()
{
new PublicTransport()
{
ArrivalTimeRemaining = 4,
Description = "FALCHERA",
IsRealTime = true,
Number = 4,
TransportType = TransportTypes.Tram
},
new PublicTransport()
{
ArrivalTimeRemaining = 12,
Description = "FALCHERA",
IsRealTime = false,
Number = 46,
TransportType = TransportTypes.Bus
}
})
{
StopDescription = "CORRADINO",
StopNumber = "233",
},
...
Then use following Collectionview in the NearBusStopsView.xaml
<RefreshView Grid.Column="0"
Grid.Row="2"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
Command="{Binding DownloadTextCommand}"
ZIndex="0">
<CollectionView
Margin="0,15,0,0"
IsGrouped="true"
ItemsSource="{Binding PublicTransportStops}">
<CollectionView.GroupHeaderTemplate>
<DataTemplate x:DataType="models:PublicTransportStop">
<Grid RowDefinitions="50,1,*"
ColumnDefinitions="*">
<Border StrokeShape="RoundRectangle 12 12 0 0"
StrokeThickness="0"
BackgroundColor="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource SecondaryDarkText}}"/>
<Grid RowDefinitions="*"
ColumnDefinitions="*,50,30"
Padding="15,0,15,0">
<HorizontalStackLayout Grid.Column="0"
VerticalOptions="Center">
<Label FontFamily="InterMedium"
Text="{Binding StopNumber, Mode=OneWay, StringFormat='Fermata {0}'}"
LineHeight="1.3"
TextColor="{StaticResource White}"
Margin="0,0,12,0"
FontSize="15"/>
<Label FontFamily="InterRegular"
Text="{Binding StopDescription, Mode=OneWay}"
TextColor="{StaticResource White}"
LineHeight="1.3"
FontSize="15"/>
</HorizontalStackLayout>
<Label Grid.Column="1"
LineHeight="1.3"
FontSize="16"
Text="{Binding Distance, Mode=OneWay, StringFormat='{0}m'}"
TextColor="{StaticResource White}"
HorizontalOptions="Center"
FontFamily="InterSemiBold"
VerticalOptions="Center"/>
<ImageButton Grid.Column="2"
HeightRequest="30"
CornerRadius="50"
Command="{Binding StarUnStarCommand, Source={x:RelativeSource AncestorType={x:Type viewModels:NearBusStopsViewModel} }}"
CommandParameter="{Binding .}"
Source="rate_star_icon"
Clicked="ImageButton_Clicked"
Grid.Row="0">
<ImageButton.Triggers>
<DataTrigger TargetType="ImageButton" Binding="{Binding IsStared}" Value="True">
<Setter Property="Source" Value="rate_star_filled_icon"></Setter>
</DataTrigger>
<DataTrigger TargetType="ImageButton" Binding="{Binding IsStared}" Value="False">
<Setter Property="Source" Value="rate_star_icon"></Setter>
</DataTrigger>
</ImageButton.Triggers>
</ImageButton>
</Grid>
<BoxView BackgroundColor="{AppThemeBinding Light={StaticResource Gray100}, Dark={StaticResource White}}"
Grid.Column="0"
Grid.Row="1"/>
</Grid>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:PublicTransport">
<Grid RowDefinitions="42,32,1"
ColumnDefinitions="30,*,.6*">
<Border StrokeThickness="0"
HeightRequest="30"
Grid.Column="0"
WidthRequest="30"
VerticalOptions="Center"
StrokeShape="RoundRectangle 6"
BackgroundColor="{StaticResource Primary}">
<Image Source="filter_bus_icon"
Aspect="Center">
<Image.Behaviors>
<toolkit:IconTintColorBehavior TintColor="White"/>
</Image.Behaviors>
<Image.Triggers>
<DataTrigger TargetType="Image" Binding="{Binding TransportType, Converter={toolkit:EnumToIntConverter}}" Value="0">
<Setter Property="Source" Value="filter_bus_icon"/>
</DataTrigger>
<DataTrigger TargetType="Image" Binding="{Binding TransportType, Converter={toolkit:EnumToIntConverter}}" Value="1">
<Setter Property="Source" Value="filter_tram_icon"/>
</DataTrigger>
</Image.Triggers>
</Image>
</Border>
<Label Text="{Binding Number, Mode=OneWay, StringFormat='№ {0}'}"
FontSize="18"
Margin="8,0,0,0"
FontFamily="InterSemiBold"
VerticalOptions="Center"
Grid.Column="1"/>
<cts:StatusIndicator Grid.Column="2" />
<Image Source="arrow_down_left_icon"
Aspect="Center"
Grid.Row="1"/>
<Label Text="{Binding Description, Mode=OneWay, StringFormat='Direzione: {0}'}"
FontSize="14"
Grid.Row="1"
VerticalOptions="Center"
FontFamily="InterRegular"
Grid.Column="1"/>
<HorizontalStackLayout Grid.Row="1"
Spacing="8"
HorizontalOptions="EndAndExpand"
Grid.Column="2">
<Image Source="clock_icon"
VerticalOptions="Center"
Aspect="Center"/>
<Label Text="{Binding ArrivalTimeRemaining, Mode=OneWay, StringFormat='{0} min'}"
FontSize="17"
HorizontalTextAlignment="End"
VerticalOptions="Center"
FontFamily="InterMedium"/>
</HorizontalStackLayout>
<BoxView BackgroundColor="{AppThemeBinding Light={StaticResource Gray100}, Dark={StaticResource White}}"
Grid.Column="0" Grid.ColumnSpan="3"
Grid.Row="2"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</RefreshView>
In the end, do not forget to add following click event in the NearBusStopsView.xaml.cs
.
private async void ImageButton_Clicked(object sender, EventArgs e)
{
var btn = (ImageButton)sender;
if (btn != null)
{
await btn.ScaleTo(0.8, 200, Easing.Default);
await btn.ScaleTo(1, 200, Easing.SpringOut);
}
}
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.