VerticalStackLayout with expanded children - xaml

According to MS Docs VerticalStackLayout is more performant alternative to StackLayout. Apparently this is because the Orientation property does not need to be calculated.
But I can't make VerticalStackLayout work with expanded children the same way as with StackLayout. I can't find any information on why VerticalStackLayout does not work with expanded children, see the example below.
How can I make VerticalStackLayout behave the same way as StackLayout with children that have AndExpand vertical option?
Code example
StackLayout -- the correct behavior, BoxViews are expanded
<StackLayout Orientation="Vertical" BackgroundColor="Yellow">
<BoxView BackgroundColor="White" VerticalOptions="StartAndExpand" />
<BoxView BackgroundColor="Red" VerticalOptions="StartAndExpand" />
</StackLayout>
VerticalStackLayout -- BoxViews are not expanded at all
<VerticalStackLayout BackgroundColor="Yellow">
<BoxView BackgroundColor="White" VerticalOptions="StartAndExpand" />
<BoxView BackgroundColor="Red" VerticalOptions="StartAndExpand" />
</VerticalStackLayout>
Result:

This is a known issue on maui you can follow up it on github issue.

Related

Stretch BindableLayout.ItemTemplate in Maui horizontally

I have a HorizontalStackLayout with elements in it added via the BindableLayout.Itemsource.
This is an example of what I mean:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StackLayoutStretchTest.MainPage">
<VerticalStackLayout>
<HorizontalStackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="Green">
<BindableLayout.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Baboon</x:String>
<x:String>Capuchin Monkey</x:String>
<x:String>Blue Monkey</x:String>
<x:String>Squirrel Monkey</x:String>
<x:String>Golden Lion Tamarin</x:String>
<x:String>Howler Monkey</x:String>
<x:String>Japanese Macaque</x:String>
</x:Array>
</BindableLayout.ItemsSource>
<BindableLayout.ItemTemplate>
<DataTemplate>
<Label Text="{Binding .}"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="Center"
TextColor="White"
BackgroundColor="DarkBlue"/>
</DataTemplate>
</BindableLayout.ItemTemplate>
</HorizontalStackLayout>
<VerticalStackLayout HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Label Text="Text"
HorizontalTextAlignment="Center"
TextColor="Black"
BackgroundColor="White"/>
</VerticalStackLayout>
</VerticalStackLayout>
</ContentPage>
How can I make the Labels(Blue) FillAndExpand into the free space(Green)?
The Maui learn page says:
A HorizontalStackLayout only respects the alignment preferences on
child views that are in the opposite direction to the orientation of
the layout.
Is there a way to stretch the children, or what is the appropriate "container" for this use case?
Please be noted that it's a known issue that being tracked in [Bug] LayoutOptions Expand not work in HorizontalStackLayout and VerticalStackLayout . To be clear, the AndExpand options are deprecated, and are not supported in the new HorizontalStackLayout and VerticalStackLayout. As an alternative solution, you can achieve the same layout with a Grid. Or you can continue to use StackLayout for another choice.

How To Use Different Alignments for Elements in XAML AbsoluteLayout (Xamarin.Forms)

In the following XAML, I have a Frame that contains an AbsoluteLayout that contains an Image and a Label. I want the Image to be left justified and the Label to be centered (in the entire AbsoluteLayout object). Here is my XAML:
<Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<AbsoluteLayout BackgroundColor="Black">
<Image Source="{local:ImageResource App.Raindrops.png}"
WidthRequest="40"
HeightRequest="60" />
<Label Text="Sprinkle"
HorizontalOptions="Center"
VerticalOptions="Center"
TextColor="White"
FontSize="36"/>
</AbsoluteLayout>
</Frame>
No matter what HorizontalOptions and VerticalOptions I use, I always get the following...
Notice that the label is not centered. Am I using the wrong layout? Am I missing, or using some wrong, attributes?
I am building the application in Visual Studio as a Xamarin.Forms app, and the deployment is being done to the standard Visual Studio Android emulator.
I found one solution here (which also has a great discussion on overlaying in XAML). The modified XAML is:
<Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<AbsoluteLayout BackgroundColor="Black">
<Image
Source="{local:ImageResource App.Raindrops.png}"
WidthRequest="50"
HeightRequest="60"/>
<Label
Text="Sprinkle"
TextColor="White"
FontSize="36"
AbsoluteLayout.LayoutBounds="0.5, 0.5, -1, -1"
AbsoluteLayout.LayoutFlags="PositionProportional"/>
</AbsoluteLayout>
</Frame>
... and the result is this ...
... which is exactly what I wanted.
By the way, I came across this little tidbit in the documentation page for AbsoluteLayout:

Xamarin.Forms: how to automatically hide first CollectionView

I work on a Xamarin.Forms app that will contain a page with 2 CollectionView items:
an horizontal CollectionView that will display events
a vertical CollectionView that will display posts
I would like that the first list is progressively hidden as soon as the user starts to scroll on the second list.
We can found this behaviour on a sample from Syncfusion: but they use a SfRotator as control for the horizontal list:
I've tried to reproduce the same behaviour on my page, but it doesn't work as expected. My horizontal list is not hidden until I scroll vertically on this first list itself. If I scroll on the second vertical list, the first list is still visible:
My XAML looks like this:
<ContentPage.Content>
<RefreshView x:DataType="vm:NewsViewModel"
IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}">
<ScrollView>
<StackLayout Padding="16" Spacing="16">
<CollectionView x:Name="EventsListView"
ItemsSource="{Binding Events}"
HeightRequest="250"
VerticalScrollBarVisibility="Never"
SelectionMode="None">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal"
ItemSpacing="20" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ctrl:ShadowFrame BackgroundColor="Red">
<StackLayout x:DataType="model:Event" >
<Label Text="{Binding Name}" />
<Image Source="{Binding Image}" />
</StackLayout>
</ctrl:ShadowFrame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<CollectionView x:Name="NewsListView"
ItemsSource="{Binding News}"
VerticalScrollBarVisibility="Never"
SelectionMode="None">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"
ItemSpacing="20" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ctrl:ShadowFrame>
<StackLayout x:DataType="model:News">
<Label Text="{Binding Description}" />
<Label Text="{Binding Date}" />
<Image Source="{Binding Image}" />
</StackLayout>
</ctrl:ShadowFrame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ScrollView>
</RefreshView>
</ContentPage.Content>
=> Is there a way to achieve this?
Quick reminder that you Shouldn't use Scrollable Elements inside other Scrollable Element, it usually breaks how both work, Quoting:
Xamarin doesn't recommend using the ListView, WebView, or ScrollView
inside a ScrollView. Microsoft Xamarin.Forms Official Documentation
says that ScrollViews should not be nested. In addition, ScrollViews
should not be nested with other controls that provide scrolling, like
ListView and WebView.
And this is what happening:
The ScrollView isn't actually scrolling, the Vertical CollectionView is the one giving the Illusion that the page is scrolling, meaning that the Horizontal one is always on top.
How to fix it?
To fix this, you should remove the Vertical CollectionView and use some kind of Repeater View, this Post will guide you on how to achieve it.

How to get FAB to float over WebView in Xamarin XAML

I'm trying to setup a XAML form definition which shows a WebView but which has a Floating Action Button over the bottom right.
If I use an AbsoluteLayout, the FAB appears correctly over the WebView. However, due to the Height/WidthRequest of the Webview, it is displayed at full size - the text disappears off the right side and doesn't wrap, so the page doesn't scroll.
<ContentPage ...snip... Title="Document">
<StackLayout Padding="5,5,5,5" HorizontalOptions="FillAndExpand" Orientation="Vertical">
<WebView x:Name="webViewDocument" WidthRequest="1000" HeightRequest="1000" />
<Label Text="{Binding UpdatedWhen, StringFormat='Last Updated: {0:dd MMM yyyy HH:mm}'}"
VerticalTextAlignment="Center" HorizontalTextAlignment="End" FontSize="Small" />
<customControls:ImageButton x:Name="fab"
Source="{markupExtensions:PlatformImage SourceImage='IconFAB'}"
Command="{Binding AddCommand}"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0.95,0.975,-1,-1"
Margin="10" />
</StackLayout>
</ContentPage>
If I use a StackLayout, the WebView sizes and scrolls correctly, however the FAB occupies a full width strip at the bottom of the screen and the text does not appear behind it - the WebView stops above it.
I've spent the last hour and a half trying every combination of nested Layout I can think of to solve this and just can't get it right - can some kind layout genius out there please tell me how I can solve this.
Thanks
Use a Grid and do not indicate rows or columns.
Something like this:
<Grid Padding="5,5,5,5"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<WebView x:Name="webViewDocument"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand" />
<Label Text="{Binding UpdatedWhen, StringFormat='Last Updated: {0:dd MMM yyyy HH:mm}'}"
VerticalOptions="End"
HorizontalOptions="Center"
HorizontalTextAlignment="End"
FontSize="Small" />
<customControls:ImageButton x:Name="fab"
Source="{markupExtensions:PlatformImage SourceImage='IconFAB'}"
Command="{Binding AddCommand}"
VerticalOptions="End"
HorizontalOptions="End"
Margin="10" />
</Grid>
This should work for you.

Add shadow to a Label - Xamarin.Forms

I would like to add drop shadow to a Label. This label is overlapped in the Page, like an always visible control that opens a filtering page.
Please find a gif attached with my screen:
Here's my XAML:
<!-- **** Filter button **** -->
<Label
Margin="0,0,10,10"
WidthRequest="50"
HeightRequest="50"
HorizontalOptions="End"
VerticalOptions="End"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
FontSize="30"
Style="{DynamicResource FilterAction}"
Text=""
BackgroundColor="{StaticResource ComplementColor}"
FontFamily="{x:Static artina:FontAwesome.FontName}"
TextColor="White">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding btn_open_filter_businesses_click}" />
</Label.GestureRecognizers>
</Label>
<templates:Badge
BadgeText="{Binding number_of_filters_selected}"
BadgeTextColor="White"
BadgeBackgroundColor="#1DBDFF"
HorizontalOptions="End"
VerticalOptions="End"
TranslationX="-4"
TranslationY="-4"
IsVisible="{Binding number_of_filters_selected, Converter={StaticResource filterVis}"
x:Name="filtersCountBagde">
<templates:Badge.GestureRecognizers>
<TapGestureRecognizer Command="{Binding btn_open_filter_businesses_click}" />
</templates:Badge.GestureRecognizers>
</templates:Badge>
I would like something like Gmail, find the example below:
Any help would be appreciated.
You can use Xamarin Effects to achieve a shadow on your button. There is a code sample that you can download here which should get you started:
Shadow Effect
It will involve creating platform-specific implementations for your shadow.
You could also try the idea put forward in this similar question.