Xamarin.Forms StackLayout/BindableLayout height calculation BUG? - Text wrapping breaks layout - c#

I've encountered a problem in Xamarin.Forms while trying to display grouped lists of items in a BindableLayout.
Following scenario:
I've want to display groups of items with a title in a frame, and the items in another frame underneath. Like in the following screenshot:
This works fine for me until the point, an item is too long and needs a line break, then the whole layout breaks and the groups overlap:
I tried removing the ScrollView, removing the TitleFrame but none works; it seems that the height calculation of the frame containing the items does ignore the labels wrapped height during layouting of the outer StackLayout.
Is there some issue with my code, or is it a BUG in Xamarin?
Please find my example code here at GitHub.
PS: The issue is on Android AND iOS.
EDIT://
Code of page as requested:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamarinTestProject.MainPage">
<AbsoluteLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Padding="24">
<ScrollView AbsoluteLayout.LayoutBounds="0,0,1,1" AbsoluteLayout.LayoutFlags="All" Margin="0,0,0,75" >
<StackLayout HorizontalOptions="Fill" Padding="0" Margin="0" BindableLayout.ItemsSource="{Binding ItemContainers}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<AbsoluteLayout Margin="0" >
<!-- TITLE -->
<Frame AbsoluteLayout.LayoutBounds="0,0,40,40" AbsoluteLayout.LayoutFlags="None" Margin="0" Padding="0" BackgroundColor="Gray" BorderColor="Green" >
<Label Text="{Binding Title}" VerticalOptions="Center" HorizontalOptions="Center" />
</Frame>
<!-- ITEMS -->
<Frame AbsoluteLayout.LayoutBounds="0,52,1,AutoSize" AbsoluteLayout.LayoutFlags="WidthProportional" Background="Gray" BorderColor="Red">
<StackLayout Padding="0" Margin="0" BindableLayout.ItemsSource="{Binding Items}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Label Text="{Binding .}" />
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</Frame>
</AbsoluteLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
<Button AbsoluteLayout.LayoutBounds="0.65,1,0.25,50" AbsoluteLayout.LayoutFlags="PositionProportional, WidthProportional" Text="Add" Command="{Binding AddCommand}" />
<Button AbsoluteLayout.LayoutBounds="1,1,0.25,50" AbsoluteLayout.LayoutFlags="PositionProportional, WidthProportional" Text="Clear" Command="{Binding ClearCommand}" />
<StackLayout Orientation="Horizontal" AbsoluteLayout.LayoutBounds="0,1,0.45,50" AbsoluteLayout.LayoutFlags="PositionProportional, WidthProportional" >
<Label Text="Multiline" FontSize="Small" HorizontalOptions="EndAndExpand" VerticalOptions="Center" />
<Switch HorizontalOptions="End" VerticalOptions="Center" IsToggled="{Binding Multiline}" />
</StackLayout>
</AbsoluteLayout>

Related

How to adjust the components for screens of different sizes (Responsive Layout)

I have a login screen that I tested on different devices and found that the components do not fit on any screen. Could someone explain to me how I can create adpative screens
<StackLayout Margin="20" VerticalOptions="Center" HorizontalOptions="Center">
<!--<Image x:Name="PicLogo" WidthRequest="100" HeightRequest="100" Aspect="AspectFit" VerticalOptions="Center" />-->
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand" Margin="30">
<StackLayout Orientation="Horizontal">
<Image x:Name="PicUser" WidthRequest="30" HeightRequest="30" Aspect="AspectFit" VerticalOptions="Center" />
<local:RoundedEntry x:Name="txtUsuario" PlaceholderColor="Gray" Placeholder="ID do utilizador..." WidthRequest="220" ></local:RoundedEntry >
</StackLayout>
<StackLayout Orientation="Horizontal" Margin="0,10,0,0">
<Image x:Name="PicPass" WidthRequest="30" HeightRequest="30" Aspect="AspectFit" VerticalOptions="Center"/>
<local:RoundedEntry x:Name="txtSenha" PlaceholderColor="Gray" Placeholder="Palavra Passe..." IsPassword="True" VerticalOptions="FillAndExpand" WidthRequest="220"></local:RoundedEntry>
</StackLayout>
<StackLayout Orientation="Horizontal" Margin="0,0,0,0" HorizontalOptions="Center">
<Label x:Name="LbEsquecer" Text="Esqueceu a palavra-Passe?" TextColor="White" />
</StackLayout>
<StackLayout x:Name="StkBotao" Margin="0,10,0,0">
<Button x:Name="CmdLogin" Text="Iniciar Sessão" BackgroundColor="#00a1e3" TextColor="White" FontSize="13.8" HorizontalOptions="EndAndExpand" WidthRequest="200"></Button>
</StackLayout>
<!--<Button x:Name="CmdHelp" Text="..." BackgroundColor="#00a1e3" HeightRequest="50" TextColor="White" BorderRadius="10" WidthRequest="40" HorizontalOptions="End"></Button>
<StackLayout Orientation="Horizontal">
<Button x:Name="CmdA" Text="FAQs" BackgroundColor="LightGray" BorderRadius="8"></Button>
<Button x:Name="CmdB" Text="Chat" BackgroundColor="LightGray" BorderRadius="8"></Button>
<Button x:Name="CmdC" Text="Ajuda" BackgroundColor="Yellow" BorderRadius="8"></Button>
</StackLayout>-->
</StackLayout>
</StackLayout>
</ContentPage>
You basically needs to play with the following properties for each layout:
HorizontalOptions
VerticalOptions
For example, your parent StackLayout should have this properties set to FillAndExpand so it covers the whole screen on height and width. The immediately child should be vertically centered and also horizontally filled. Like so:
<!-- Parent stacklayout starts -->
<StackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<!-- Immediately child stacklayout starts -->
<StackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand">
<!-- Your login markup starts -->
<!-- Your login markup ends -->
</StackLayout>
<!-- Immediately child stacklayout ends -->
</StackLayout>
And the rest of childs falls into this base layout. Remember you are on a stacklayout where elements are placed in a stack manner.
Also don't forget to use HorizontalTextAlignment to actually align the elements under your stacklayouts, like so:
<!-- Parent stacklayout starts -->
<StackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<!-- Immediately child stacklayout starts -->
<StackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand">
<!-- Your login markup starts -->
<Label Text="Hi there!" HorizontalTextAlignment="Center" />
<Label Text="Here you have some tips" HorizontalTextAlignment="Center" />
<!-- Your login markup ends -->
</StackLayout>
<!-- Immediately child stacklayout ends -->
</StackLayout>
Example add views templates.
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
x:Class="MyAp.Views.MyNewView"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:MyApp.Views">
<ContentView.Content>
<OnIdiom x:TypeArguments="View">
<OnIdiom.Desktop>
<views:NewView_Desktop />
</OnIdiom.Desktop>
<OnIdiom.Tablet>
<views:NewView_Tablet />
</OnIdiom.Tablet>
<OnIdiom.Phone>
<views:NewView_Phone />
</OnIdiom.Phone>
</OnIdiom>
</ContentView.Content>
Reference view, that will be independent.
xmlns:views="clr-namespace:MyApp.Views
<views:MyFirstView />
<views:MySecondView />

How to give a shadow effect to a frame in xamarin forms

I am new in xamarin I wan to add a shadow effect to my frame and avoid the top border line of my frame, I tried "hasShadow" property of frame but that doesn't help me. How can I do this.
Please help me
Here is my Xaml
<ListView x:Name="lv_search" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" RowHeight="105" ItemTapped="lv_search_ItemTapped"
SeparatorColor="White" BackgroundColor="Black" Margin="0,15,0,0">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="White">
<Grid Margin="20,10,0,10" BackgroundColor="White">
<Frame BackgroundColor="White" >
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal" HorizontalOptions="StartAndExpand" VerticalOptions="FillAndExpand" Margin="0,0,10,0">
<AbsoluteLayout HorizontalOptions="StartAndExpand">
<Image Source="ellipse_1" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand"
AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0.01,0.4,1,1" BackgroundColor="White"/>
<Image Source="{Binding Image}" AbsoluteLayout.LayoutBounds="0.02,0.4,1,1" AbsoluteLayout.LayoutFlags="All"
HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" />
</AbsoluteLayout>
<StackLayout AbsoluteLayout.LayoutBounds="0.035,0.5,1,1" AbsoluteLayout.LayoutFlags="All" Orientation="Horizontal"
HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand">
<Label x:Name="lbl_categories" HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand"
Margin="10,0,0,0" FontFamily="Proxima-Nova-Semibold" TextColor="#222222" Text="{Binding Title}"
LineBreakMode="WordWrap" HorizontalTextAlignment="Start" FontSize="17.3" FontAttributes="Bold"/>
</StackLayout>
</StackLayout>
<Image HorizontalOptions="EndAndExpand" VerticalOptions="Center" Source="arrow"
AbsoluteLayout.LayoutBounds="0.9,0.3,0,0.3" AbsoluteLayout.LayoutFlags="All" />
</StackLayout>
</Frame>
</Grid>
<Image Source="img_frm" Margin="15,0,0,0" AbsoluteLayout.LayoutBounds="1,0.5,1,1" HorizontalOptions="StartAndExpand"
AbsoluteLayout.LayoutFlags="All"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The code gives this output
But I want a page like this
The page difference is marked by blue ink.
This article by Alex Dunn looks like what you want exactly:
https://alexdunn.org/2018/06/06/xamarin-tip-dynamic-elevation-frames/
Note that you can control the Elevation as much as you want
You can use the HasShadow="True" atribute on Frame definition.
Where did you place the HasShadow? It need to be like this
<i> <Frame HasShadow="True" ...> </Frame> </i>

Xamarin forms :Size of an image inside a carousel view

I have a carousel view inside a stasklayout which is also inside a scroll view, the carousel view contains an image which is displayed in miniature, I want that the image is displayed in actual size.How to do it please?
<ScrollView>
<StackLayout>
<StackLayout VerticalOptions="Fill">
<cv:CarouselView ItemsSource="{Binding MediaItems}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
<cv:CarouselView.ItemTemplate>
<DataTemplate>
<Image Aspect="AspectFit" HorizontalOptions="FillAndExpand" Source="{Binding Uri}" />
</DataTemplate>
</cv:CarouselView.ItemTemplate>
</cv:CarouselView>
</StackLayout>
<StackLayout Orientation="Vertical" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Label Text="{Binding tappedItem.ShortDesc}" IsVisible="{Binding ShortText,Mode=OneWay}" FontAttributes="Italic" FontFamily="Sans-serif" />
<Label Text="{Binding tappedItem.LongDesc}" IsVisible="{Binding LongText,Mode=OneWay}" FontAttributes="Italic"/>
<local:BorderlessButton Text="{Binding BtnText}" FontSize="Medium" TextColor="DodgerBlue" FontAttributes="None" Clicked="Button_Clicked" />
</StackLayout>
</ScrollView>
See is there any property for caursoel view like HasUnEvenRows property in listview.

Xamarin Forms Android Keyboard moves whole Page upwards

I was trying to write a Xamarin.Forms chat-app.
The problem is: On Android, as soon as the keyboard shows up the whole page (including the ActionBar) moves upwards. I could fix the problem on IOS by using a NuGet package that resizes the page.
I already tried to set WindowSoftInputMode = Android.Views.SoftInput.AdjustResize in the MainActivity.cs in the Android project but it didn't work.
I also tried to resize the page manually by recalculating the screen size, but I haven't found a solution to get the keyboard size for an exact calculation on different devices.
Has anyone had the same problem before?
Is there an official Xamarin.Forms solution for all supported platforms?
This is my chat layout so far:
<ContentPage.Content>
<StackLayout Padding="0">
<ScrollView>
<ListView HasUnevenRows="true" x:Name="lvChat" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" VerticalOptions="Fill" HorizontalOptions="Fill" Padding="5">
<Label Text="{Binding Author, StringFormat='{0}: '}" TextColor="Navy" FontSize="14" />
<Label Text="{Binding Text}" TextColor="Black" FontSize="15" />
<Label Text="{Binding Time}" TextColor="Black" FontSize="14" />
<!-- Format for time.. , StringFormat='{0:HH:mm}' -->
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollView>
<StackLayout Orientation="Horizontal" Padding="0" Margin="5, 5, 5, 5">
<Entry Keyboard="Chat" x:Name="tbxChatInput" HorizontalOptions="FillAndExpand" Placeholder="Send a Message..." />
<Button x:Name="btnSendMsg" HorizontalOptions="End" Text="Send" Margin="5"/>
</StackLayout>
</StackLayout>
Thanks in advance!
Hi try putting the stacklayout that contains your input and send button inside the scrollview, that way when you tap on the input it pushes the keyboard up shows you your input and the rest of your chat works fine on both iOS and Android. Try this:
<ContentPage.Content>
<StackLayout Padding="0">
<ScrollView>
<StackLayout>
<ListView HasUnevenRows="true" x:Name="lvChat" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" VerticalOptions="Fill" HorizontalOptions="Fill" Padding="5">
<Label Text="{Binding Author, StringFormat='{0}: '}" TextColor="Navy" FontSize="14" />
<Label Text="{Binding Text}" TextColor="Black" FontSize="15" />
<Label Text="{Binding Time}" TextColor="Black" FontSize="14" />
<!-- Format for time.. , StringFormat='{0:HH:mm}' -->
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackLayout Orientation="Horizontal" Padding="0" Margin="5, 5, 5, 5">
<Entry Keyboard="Chat" x:Name="tbxChatInput" HorizontalOptions="FillAndExpand" Placeholder="Send a Message..." />
<Button x:Name="btnSendMsg" HorizontalOptions="End" Text="Send" Margin="5"/>
</StackLayout>
</StackLayout>
</ScrollView>
</StackLayout>
</ContentPage.Content>
Try setting windowSoftInputMode in your Android Manifest for example:
<application ... >
<activity
android:windowSoftInputMode="adjustResize" ... >
...
</activity>
...
</application>

Full Width Image with Cropped Height in Xamarin.Forms ListView

I'm loading a list of items and I'm trying to lay out the image (from a URL) as the background with full width and the height cropped if necessary, and overlay some text and images on top. I can't get the image to expand to the full width and height no matter what I do. I've tried about everything I can think of but here's how the code looks at this point:
<StackLayout x:Name="mainStack" Orientation="Vertical">
<Label x:Name="errorMsg" IsVisible="False" />
<ActivityIndicator IsRunning="False" IsVisible="False" x:Name="activityIndicator" />
<ListView CachingStrategy="RecycleElement" IsPullToRefreshEnabled="true" Refreshing="OnRefreshItems" ItemSelected="LoadDetails" HorizontalOptions="CenterAndExpand" Margin="20" RowHeight="280">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Spacing="0" HorizontalOptions="FillAndExpand">
<AbsoluteLayout HeightRequest="200" HorizontalOptions="FillAndExpand">
<Image Aspect="AspectFill" Source="{Binding ImageUrl}" HorizontalOptions="FillAndExpand" HeightRequest="200" />
<Image Aspect="AspectFill" HorizontalOptions="FillAndExpand" Source="opacity.png" />
<Image Source="favorite.png" HeightRequest="50" />
<StackLayout Orientation="Horizontal" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="1,0,.3,.3" >
<Image Source="shareList.png" HeightRequest="30" />
<Image Source="shareList.png" HeightRequest="30" />
</StackLayout>
<StackLayout Orientation="Vertical" VerticalOptions="EndAndExpand" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds=".1,.7,.8,.1">
<Label Text="{Binding StartFormatted}" TextColor="#ffffff" Style="{StaticResource dateList}" />
<Label Text="{Binding Name}" TextColor="#ffffff" Style="{StaticResource h1Style}" />
</StackLayout>
</AbsoluteLayout>

Categories

Resources