Extra Space when i add ListView inside a Frame layout - xamarin.forms

enter image description hereI am not clear what am I missing. Extra space at the bottom of the list. please check the screenshot attached below.
<ListView ItemSelected="ListView_ItemSelected" VerticalOptions="Start" ItemsSource="{Binding RelayList}" SeparatorVisibility="Default" SeparatorColor="Gray" HasUnevenRows="True" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<Grid BackgroundColor="#E6E6E6" VerticalOptions="End">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<StackLayout Orientation="Vertical" Grid.Column="0" Padding="10,10,10,0" VerticalOptions="Start">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding RelayName}" TextColor="Black" FontSize="Small" />
<Label Text="{Binding RelayType}" TextColor="Black" FontSize="Small" />
</StackLayout>
</StackLayout>
<Image Grid.Column="1" Source="nextbtn.png" HorizontalOptions="EndAndExpand" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</Frame>
</StackLayout>

This is happening because you are using a Frame, A Frame has a default Padding of 20.
Which can be confirmed here
So now the there are two things you can do set the Padding to 0 in the Frame so you do not see this spacing(Can be done on L,T,R,B differently using the 4 parameters)
Or you can remove the Frame all together.

Related

Grid layout in Xamarin Forms

Currently, I've got a ListView implementation that looks something like this:
{Alert1}
{Alert2}
{Alert3}
{Alert4}
{Alert5}
{Alert6]
{Alert7}
xaml:
<ListView Grid.Row="4"
ItemsSource="{Binding Alerts}"
HasUnevenRows="True"
VerticalOptions="Start"
SeparatorVisibility="None" Margin="10,0"
x:Name="AlertsList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame BackgroundColor="#333333" Margin="0,5" Padding="5">
<StackLayout Margin="0" Padding="0">
<Label
Text="{Binding Name, Mode=OneWay}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
Margin="0" />
<Label
Text="{Binding Value, Mode=OneWay}"
HorizontalOptions="Center"
FontSize="Medium"
Margin="0" />
</StackLayout>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Any suggestion on how to modify this so that the output is displayed in a 2 column grid instead with equal width columns such as?
{Alert1}{Alert2}
{Alert3}{Alert4}
{Alert5}{Alert6]
{Alert7}
I'm using Xamarin Forms v2.3.3
As Jason said,you could upgrade your XF version and use CollectionView with its ItemsLayout property.
<CollectionView ItemsSource="{Binding Alerts}"
ItemsLayout="VerticalGrid, 2">
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame BackgroundColor="#333333" Margin="0,5" Padding="5">
<StackLayout Margin="0" Padding="0">
<Label
Text="{Binding Name, Mode=OneWay}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
Margin="0" />
<Label
Text="{Binding Value, Mode=OneWay}"
HorizontalOptions="Center"
FontSize="Medium"
Margin="0" />
</StackLayout>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
The more you could refer to the doc.

Abysmal list performance

An item template that includes a SkiaSharp control displaying svg, a SwipeView and some labels,
is taking forever to load when navigating to the page.
I am using StackLayout with BindableLayout.ItemSource and ItemTemplate.
Using CollectionView will let the page load much faster, but then every attempt to scroll down will slow the app for a moment, while the CollectionView generate the next batch of items.
I have moved all the code generating the items source to background, so the only thing happening on the ui thread is the binding to the ObservableCollection from the viewmodel, and drawing it.
I have also tried reducing the layouts in the item template, but it did not improve loading speed.
Xaml for page:
<DataTemplate x:Key="DataTemplateReportsItemAction">
<StackLayout Orientation="Horizontal">
<effectsView:SfEffectsView Style="{StaticResource StyleRippleEffectReportAction}">
<effectsView:SfEffectsView.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ActionCommand}" />
</effectsView:SfEffectsView.GestureRecognizers>
<image:SVGImage ImageSource="{Binding IconName}"
Style="{StaticResource StyleSVGImageReportRowAction}" />
</effectsView:SfEffectsView>
<BoxView Style="{StaticResource StyleBoxViewReportItemAction}"
IsVisible="{Binding IsLast, Converter={StaticResource BoolToReverseBoolConverter}}" />
</StackLayout>
</DataTemplate>
<ControlTemplate x:Key="DataTemplateReportsItemCellDefault">
<StackLayout Orientation="Horizontal"
HorizontalOptions="FillAndExpand"
BindingContext="{TemplateBinding BindingContext}">
<StackLayout Orientation="Vertical"
HorizontalOptions="FillAndExpand"
VerticalOptions="Center">
<Label Style="{StaticResource StyleLabelReportCellTop}"
Text="{Binding DisplayValue}"
TextColor="{Binding ColorName, TargetNullValue={StaticResource ColorLabelReportCell}, FallbackValue={StaticResource ColorLabelReportCell}}" />
<Label Style="{StaticResource StyleLabelReportCellBottom}"
Text="{Binding DisplayTitle}"
TextColor="{Binding ColorName, TargetNullValue={StaticResource ColorLabelReportCell}, FallbackValue={StaticResource ColorLabelReportCell}}" />
</StackLayout>
<BoxView Style="{StaticResource StyleBoxViewReportItemCell}"
IsVisible="{Binding IsLast, Converter={StaticResource BoolToReverseBoolConverter}}" />
</StackLayout>
</ControlTemplate>
<ControlTemplate x:Key="DataTemplateReportsItemCellTrend">
<StackLayout Orientation="Horizontal"
HorizontalOptions="FillAndExpand"
BindingContext="{TemplateBinding BindingContext}">
<StackLayout Orientation="Vertical"
HorizontalOptions="FillAndExpand"
VerticalOptions="Center">
<image:SVGImage ImageSource="{Binding IconName}"
HorizontalOptions="Center" />
<Label Style="{StaticResource StyleLabelReportCellTrend}"
Text="{Binding DisplayTitle}"
TextColor="{Binding ColorName, TargetNullValue={StaticResource ColorLabelReportCell}, FallbackValue={StaticResource ColorLabelReportCell}}" />
</StackLayout>
<BoxView Style="{StaticResource StyleBoxViewReportItemCell}"
IsVisible="{Binding IsLast, Converter={StaticResource BoolToReverseBoolConverter}}" />
</StackLayout>
</ControlTemplate>
<converters:ValueToValueConverter x:Key="CellTemplateSelector"
DefaultValue="{StaticResource DataTemplateReportsItemCellDefault}">
<converters:ValueToValueList>
<converters:ValueToValueItem OnValue="{x:Static reportenums:MobileColumnMetaType.Trend}"
ToValue="{StaticResource DataTemplateReportsItemCellTrend}" />
</converters:ValueToValueList>
</converters:ValueToValueConverter>
<DataTemplate x:Key="DataTemplateReportsItemCell">
<ContentView ControlTemplate="{Binding MobileMetaType, Converter={StaticResource CellTemplateSelector}}"
HorizontalOptions="FillAndExpand" />
</DataTemplate>
<DataTemplate x:Key="DataTemplateReportsItem">
<Grid HeightRequest="{StaticResource DoubleReportRowTotalHeight}">
<Grid.RowDefinitions>
<RowDefinition Height="{StaticResource DoubleReportRowTitleHeight}" />
<RowDefinition Height="{StaticResource DoubleReportRowSwipeHeight}" />
</Grid.RowDefinitions>
<StackLayout Margin="0,5"
Orientation="Horizontal"
HorizontalOptions="FillAndExpand"
Spacing="10">
<image:SVGImage ImageSource="{Binding LactationIcon}"
IsVisible="{Binding LactationIcon, Converter={StaticResource StringToIsVisibleConverter}}"
Style="{StaticResource StyleSVGImageReportRowLactation}" />
<Label Style="{StaticResource StyleLabelReportRowTitle}"
FontSize="{Binding UseSmallTitle, Converter={StaticResource RowFontSizeConverter}}"
Text="{Binding DisplayTitle}" />
<Label Style="{StaticResource StyleLabelReportRowTitleGroup}"
IsVisible="{Binding GroupName, Converter={StaticResource StringToIsVisibleConverter}}"
Text="{Binding GroupName}" />
<Frame Style="{StaticResource StyleFrameReportRowBadge}"
BackgroundColor="{Binding Badge.BadgeType, Converter={StaticResource BadgeColorConverter}}"
IsVisible="{Binding Badge.HasBadge}">
<Label Style="{StaticResource StyleLabelReportRowTitleBadge}"
Text="{Binding Badge.BadgeTitle}" />
</Frame>
</StackLayout>
<Grid Grid.Row="1">
<SwipeView BackgroundColor="{StaticResource ColorReportViewRowBackground}"
IsEnabled="{Binding IsEditable}"
x:Name="swipey">
<SwipeView.RightItems>
<SwipeItems Mode="Reveal"
SwipeBehaviorOnInvoked="RemainOpen">
<SwipeItemView WidthRequest="{Binding Width, Source={Reference swipey}}">
<Grid BackgroundColor="{StaticResource ColorLabelReportRowActionsBackground}">
<Grid Margin="20,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<effectsView:SfEffectsView Style="{StaticResource StyleRippleEffectReportRowClose}"
helpers:VisualTreeHelper.ReferenceObject="{Binding Source={Reference swipey}}">
<effectsView:SfEffectsView.GestureRecognizers>
<TapGestureRecognizer Tapped="OnGroupRowCloseTapped" />
</effectsView:SfEffectsView.GestureRecognizers>
<image:SVGImage Style="{StaticResource StyleSVGImageReportRowActionsClose}" />
</effectsView:SfEffectsView>
<StackLayout Grid.Column="2"
Orientation="Horizontal"
BindableLayout.ItemTemplate="{StaticResource DataTemplateReportsItemAction}"
BindableLayout.ItemsSource="{Binding ActionItems}" />
</Grid>
</Grid>
</SwipeItemView>
</SwipeItems>
</SwipeView.RightItems>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackLayout Orientation="Horizontal"
HorizontalOptions="FillAndExpand"
BackgroundColor="{StaticResource ColorTransparent}"
BindableLayout.ItemTemplate="{StaticResource DataTemplateReportsItemCell}"
BindableLayout.ItemsSource="{Binding Cells}">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.NavigateCommand, Source={RelativeSource Mode=FindAncestor, AncestorType={x:Type views:BasePage}}}"
CommandParameter="{Binding}" />
</StackLayout.GestureRecognizers>
</StackLayout>
<Frame Grid.Column="1"
Padding="0"
BackgroundColor="{StaticResource ColorReportGroupRowActionsBackground}"
IsVisible="{Binding IsEditable}">
<image:SVGImage Style="{StaticResource StyleSVGImageSwipe}" />
</Frame>
</Grid>
</SwipeView>
<Grid BackgroundColor="{StaticResource ColorTransparent}"
IsVisible="{Binding IsEditable, Converter={StaticResource BoolToReverseBoolConverter}}">
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.NavigateCommand, Source={RelativeSource Mode=FindAncestor, AncestorType={x:Type views:BasePage}}}"
CommandParameter="{Binding}" />
</Grid.GestureRecognizers>
</Grid>
</Grid>
</Grid>
</DataTemplate>
</ContentView.Resources>
<ContentView.Content>
<Grid>
<gradient:SfGradientView BackgroundBrush="{StaticResource BrushViewBackgroundGradient}" />
<Grid BackgroundColor="{StaticResource ColorReportsBrowserViewBackground}"
Margin="10,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<reports:ReportToolbarView />
<RefreshView Grid.Row="1"
IsRefreshing="{Binding IsRefreshing, Mode=TwoWay}"
Command="{Binding RefreshCommand}"
BackgroundColor="{StaticResource ColorReportsViewBackground}"
Margin="10,0">
<ScrollView HorizontalScrollBarVisibility="Never"
VerticalScrollBarVisibility="Default">
<StackLayout Orientation="Vertical">
<StackLayout BindableLayout.ItemsSource="{Binding ReportItems}"
BindableLayout.ItemTemplate="{StaticResource DataTemplateReportsItem}"
Orientation="Vertical" />
<BoxView HeightRequest="50" />
</StackLayout>
</ScrollView>
</RefreshView>
<sortfilter:SortFilterView Grid.Row="1"
VerticalOptions="Start"
IsVisible="{Binding SortFilterModel.IsVisible}" />
</Grid>
</Grid>
</ContentView.Content>
For comparison, replacing the item template with a simple Label makes the page load extremely fast.
Is there a way to load lists of items faster in Xamarin Forms?
Too many StackLayouts. Even worse, you stacked them into each other. Don't do that.
StackLayouts need a lot of layout cycles, as they have to calculate their size based on the children you have put in. If one of those children is a StackLayout as well, that will more than double the layout passes necessary to get to the final result.
And now guess what happens, when you have 50 or more items in your list. Those layout passes will have to run for each single item in your list.
My advice based on my experience would be to replace the StackLayouts with a grid and place your elements using their Grid.Row, Grid.Colum, Grid.RowSpan and Grid.Columnspan properties. Also set your grid sizes to either fixed values or use star based sizes. Don't use "Auto" as this needs more layout passes as well.

I can not specify a Height of a customView?

I created a CustomView to use in CollectionView's DataTemplate
<Frame CornerRadius="10" IsClippedToBounds="True" Padding="0" HasShadow="False" >
<AbsoluteLayout Padding="0" Margin="0">
<Image Source="image1.png" AbsoluteLayout.LayoutBounds="0,0,1,1" Aspect="AspectFill" AbsoluteLayout.LayoutFlags="All"></Image>
<Frame BackgroundColor="#fedb0a" AbsoluteLayout.LayoutBounds="0,0,0.426,0.1177" AbsoluteLayout.LayoutFlags="All" HasShadow="False">
<StackLayout Orientation="Horizontal" AbsoluteLayout.LayoutBounds="0.682,0.29,AutoSize,0.05885">
<Label Text="Hi" FontSize="Medium" VerticalOptions="CenterAndExpand"></Label>
</StackLayout>
</Frame>
<StackLayout AbsoluteLayout.LayoutBounds="0,1,1,0.2" AbsoluteLayout.LayoutFlags="All" BackgroundColor="#95000000" Orientation="Horizontal">
<StackLayout VerticalOptions="CenterAndExpand" Margin="5,0,5,0">
<Frame CornerRadius="20" IsClippedToBounds="True" Padding="0">
<Image Source="icon1.png" Aspect="AspectFill" WidthRequest="40" HeightRequest="40"></Image>
</Frame>
</StackLayout>
<StackLayout VerticalOptions="CenterAndExpand">
<Label Text="hopeshow~" FontSize="Large" TextColor="#fedb0a"></Label>
<Label Text="2020 year" FontSize="Medium" TextColor="White"></Label>
</StackLayout>
</StackLayout>
</AbsoluteLayout>
</Frame>
I placed it in my DataTemplate <vi:MyCustomView HeightRequest="40"></vi:MyCustomView> but it seems that the HeightRequest is not sequenced.
the view autosized a large view.
The WidthRequest is ok when I set a value.
How to do with it?
The layout like StackLayout and AbsoluteLayout will not fit the size of its child elements . So if you want to implement it you can use Grid instead of them .
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
//set them in the same Row and Column and they will be in the same position .
<Image Source="image1.png" Grid.Row="0" Grid.Column="0"></Image>
<Frame BackgroundColor="#fedb0a" HasShadow="False"Grid.Row="0" Grid.Column="0">
//...
</Frame>
//...other elements
</Grid>
For more details about layout you can check https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/grid

Xamarin Formns: Multiple empty rows getting created after the data in list view

PFB the code for my list view,
<ListView HasUnevenRows="true" ItemsSource="{Binding UserEmailList}" IsGroupingEnabled="true">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout Orientation="Vertical" Spacing="0" Margin="0" Padding="0">
<BoxView Style="{StaticResource separator}"></BoxView>
<Label Text="{Binding Heading}" Style="{StaticResource labelHeaderTitle}" />
<BoxView Style="{StaticResource separator}"></BoxView>
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout Orientation="Horizontal" Spacing="0" >
<StackLayout IsVisible="{Binding UserEmailDetails.HasEmailAddress}" Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<Label Text="{Binding UserEmailDetails.EmailAddress}" Style="{StaticResource labelListItem}" HorizontalOptions="FillAndExpand">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="SelectEmailAddress_Tapped" CommandParameter="{Binding UserEmailDetails}" />
</Label.GestureRecognizers>
</Label>
<Image HeightRequest="16" HorizontalOptions="End" VerticalOptions="Center" Source="arrow.png" Margin="0,0,15,0">
</Image>
</StackLayout>
<StackLayout IsVisible="{Binding UserEmailDetails.HasEmailAddress, Converter={StaticResource NotConverter}}" Padding="15,0,0,0">
<Label Text="Add email" Style="{StaticResource labelLink}">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="SelectEmailAddress_Tapped" CommandParameter="{Binding UserEmailDetails}" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Even if there are only two rows, on IOS multiple empty rows are getting populated as in the below snapshot.
Please let me know how to avoid this and hav things working in both Android and IOS
I would hide the Separator by setting SeparatorVisibility="None" on ListView Property. If you still need the Separator I would define in the ViewCell.
<ListView HasUnevenRows="true" SeparatorVisibility="None">
The other way is to put Empty Footer on List View:
<ListView>
<ListView.Footer>
<Label />
</ListView.Footer>
</ListView>
I hope one of these helps you. Let me know if anything.

How to set vertical scrollbar in Listview in xamarin.forms

I am loaded the data in List view in my page. I am able to scroll the data in List view but at the time of scrolling not showing any scrollbar at vertical. Please suggest any idea, How can I set vertical scrollbar in List view.
Sample code:
<ListView BackgroundColor="Transparent" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"
ItemsSource="{Binding DataList}" HeightRequest="{Binding DataListRowHeight}" HasUnevenRows="true" HorizontalOptions="CenterAndExpand" RowHeight="40" SeparatorColor="Transparent"
SelectedItem="null">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.GestureRecognizers>
<TapGestureRecognizer Tapped="OnItemClicked"/>
</Grid.GestureRecognizers>
<Label Text="{Binding WindowName}" Grid.Column="0" TextColor="Black" FontFamily="Avenir Book" HorizontalTextAlignment="Start" VerticalTextAlignment="Center">
</Label>
<StackLayout Orientation="Horizontal" Grid.Column= "1">
<Label Text="Curtain Type:" TextColor="Black" FontFamily="Avenir Book" FontAttributes="Bold" HorizontalTextAlignment="Start" VerticalTextAlignment="Center">
</Label>
<Label Text="{Binding Data}" TextColor="Black" FontFamily="Avenir Book" HorizontalTextAlignment="Start" VerticalTextAlignment="Center">
</Label>
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Above is the second listview sample code.

Resources