Trying to produce a Xamarin.Forms page across all devices (iOS, Android, UWP) but need the contents to be displayed as card views side-by-side like the example below.
What is the best way to achieve this? Is there any OSS library out there since I can't seem to find anything like this out-of-the-box?
EDIT: Unfortunately I forgot to mention that this is to be bindable to an Ienumerable source. Number of items is not fixed. Contents inside each card will have the same template only from different items.
Thanks
Things have moved on since the question was first asked. You can now use a CollectionView with a GridItemsLayout with a span of 2 to achieve the layout required.: Link to Xamarin Forms CollectionView documentation
So as i understood from your comments what u need to do is a Grid within a ScrollView. Here is an exmaple;
<ScrollView Orientation="Vertical">
<Grid RowSpacing="10" ColumnSpacing="10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="AUTO"/>
<ColumnDefinition Width="AUTO"/>
</Grid.ColumnDefinitions>
<Frame Grid.Row="0" Grid.Column="0">
<!--DO YOUR DESIGN FOR FRAME No. 1 HERE-->
</Frame>
<Frame Grid.Row="1" Grid.Column="0">
<!--DO YOUR DESIGN FOR FRAME No. 2 HERE-->
</Frame>
<Frame Grid.Row="2" Grid.Column="0">
<!--DO YOUR DESIGN FOR FRAME No. 3 HERE-->
</Frame>
<Frame Grid.Row="3" Grid.Column="0">
<!--DO YOUR DESIGN FOR FRAME No. 4 HERE-->
</Frame>
<Frame Grid.Row="0" Grid.Column="1">
<!--DO YOUR DESIGN FOR FRAME No. 5 HERE-->
</Frame>
<Frame Grid.Row="1" Grid.Column="1">
<!--DO YOUR DESIGN FOR FRAME No. 6 HERE-->
</Frame>
<Frame Grid.Row="2" Grid.Column="1">
<!--DO YOUR DESIGN FOR FRAME No. 7 HERE-->
</Frame>
<Frame Grid.Row="3" Grid.Column="1">
<!--DO YOUR DESIGN FOR FRAME No. 8 HERE-->
</Frame>
</Grid>
</ScrollView>
What i would truly suggest though is to search for a library that would give you the possibility to do it in ListView. This way you will reduce your hardcoded design code and obtain better and easier access to your layout.
You can use the following library which is a ListView derivative with flowing, grid-like columns support.
https://github.com/daniel-luberda/DLToolkit.Forms.Controls
Related
I want to make a design just like the picture below
[![Example][1]][1]
[1]: https://i.stack.imgur.com/Gzlj0.png
But I am not sure how to start. I have idea to make it with Frames and Grid. Something like:
<StackLayout>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Frame Grid.Row="1" BackgroundColor="Gray">
</Frame>
<Frame BackgroundColor="LightGray" Grid.Row="2">
</Frame>
</Grid>
</StackLayout>
But I have no idea how to make frame re-sizable when clicking on it. I want any kind of start
Please refer anyone from below option:
you can create custom accordion view and use it.
https://www.c-sharpcorner.com/article/simple-accordion-user-control-in-xamarin-forms/
https://kimsereyblog.blogspot.com/2016/10/build-accordion-view-in-xamarinforms.html
https://alexdunn.org/2018/04/03/xamarin-tip-build-your-own-accordionview-in-xamarin-forms/
Can you give recommendations on how to optimize the ListView?
It slows down when scrolling.
My viewCell looks like this:
<Grid BackgroundColor="{Binding ListViewCustomizer.ItemBorderColor, Source={x:Static theme:ThemeManager.Theme}}" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Grid Margin="0, 0, 0, 1"
BackgroundColor="{Binding ListViewCustomizer.ItemBackgroundColor, Source={x:Static theme:ThemeManager.Theme}}" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Grid.Triggers>
<DataTrigger Binding="{Binding IsRead}" TargetType="Grid" Value="true">
<Setter Property="BackgroundColor" Value="#bfe3fa" />
</DataTrigger>
</Grid.Triggers>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="4*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="6*"/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<ContentView Grid.RowSpan="2" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Margin="1, 1">
<ffimageloading:CachedImage x:Name="mainImage"
Source="news_placeholder.png"
LoadingPlaceholder="news_placeholder.png"
DownsampleToViewSize="false"
CacheDuration="{x:Static constant:ImageConfig.PreviewImageCacheDuration}"
ErrorPlaceholder="news_placeholder.png" Aspect="AspectFill"
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
Transformations="{Binding IsRead, Converter={StaticResource BoolToTransformationConverter}}">
<ffimageloading:CachedImage.DownsampleHeight>
<extensions:OnDeviceType x:TypeArguments="x:Double" Phone="130" Tablet="200"/>
</ffimageloading:CachedImage.DownsampleHeight>
</ffimageloading:CachedImage>
</ContentView>
<Grid Grid.Column="1" RowSpacing="0" Margin="10,10,10,0">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Label Style="{StaticResource BaseListItemLabelStyle}" FormattedText="{Binding ., Converter={StaticResource NewsItemToFormattedStringConveter}}"/>
<ctrl:ExtendedLabel
Grid.Row="1"
MultilineTrimming="True"
x:Name="content"
Style="{StaticResource ListItemContentLabelStyle}" />
</Grid>
</Grid>
</Grid>
Maybe something to replace something. Maybe should I replace all bindings with code-behind?
Help me please.
You packed quite a lot of stuff into that viewcell. Also changing data binding to code behind won't give you significant benefits performancewise.
What is happening here is that all of these elements need to run layout passes, which requires time (performance). Now multiply that with the amount of items in your ListView. Good news however is, that this multiplication factor will be in your favour once you improve your view to do less layouting.
What I would suggest:
1) Don't use "Auto" height definitions, since that will need multiple layout passes until the final height has been determined
2) Reduce the grids to one single grid and work with RowSpan and ColumnSpan properties to set your elements
3) Is there a reason why you are using a content view? If I remember correctly you should be able to put the ffimageloading.cachedimage directly into a grid.
For more information about how to optimize your xamarin forms layout performance, I would recomment this article: https://xamarininsider.com/2017/08/03/optimizing-layout-performance-in-xamarin-forms/
I'm learning Xamarin and I want to display an image as background with some texto over this image...
Just that, I manage to acomplish, but the text is displayed at the top left corner of the image.
I'd like the text to be placed at the vertical center of the image, but stick to the left side of it.
My code so far XAML:
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="20*" ></RowDefinition>
<RowDefinition Height="65*"></RowDefinition>
<RowDefinition Height="15*"></RowDefinition>
</Grid.RowDefinitions>
<RelativeLayout Grid.Row="0">
<Image Source="login.png" Aspect="Fill" />
<Label Text="Bem vindo" TextColor="White" FontSize="22"></Label>
</RelativeLayout>
<Label Grid.Row="1" Text="linha 2" BackgroundColor="Coral"></Label>
<Button Grid.Row="2" Text="linha 3" BackgroundColor="DarkRed"></Button>
</Grid>
I've tried verticalOptions and such, but with no effect.
One thing that kind of worked is settin a Maring property to the label, but that way, the label would be centered only to the device I'm testing on. Other devices, smaller or greater, the label could (and probably would) be placed at the wrong place.
Any help?
You don't need a RelativeLayout inside the Grid. The Grid itself already is able to handle views overlay besides let your code clearer.
It may works:
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="20*"></RowDefinition>
<RowDefinition Height="65*"></RowDefinition>
<RowDefinition Height="15*"></RowDefinition>
</Grid.RowDefinitions>
<Image Grid.Row="0" Grid.Column="0"
Source="login.png"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Aspect="Fill" />
<Label Grid.Row="0" Grid.Column="0"
Text="Bem vindo"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HorizontalTextAlignment="Start"
VerticalTextAlignment="Center"
TextColor="White"
FontSize="22"/>
<Label Grid.Row="1"
Text="linha 2"
BackgroundColor="Coral"/>
<Button Grid.Row="2"
Text="linha 3"
BackgroundColor="DarkRed"/>
</Grid>
I am trying to do a button with a image, and each button has a text inside...but I don't know so much about xamarin forms, I'm a beginner
And my images is little while the text is bigger than it...
I am using a grid...and inside it one other grid with 1 colunm and 1 row for each button (Image and texts)
I neet the image (that is my button) get the size of the texts that is inside it
My xml at the moment:
<!-- Buttons grid-->
<Grid HorizontalOptions="Center" Margin="20,20,20,20" RowSpacing="30" ColumnSpacing="10" BackgroundColor="Aquamarine" VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!--One of my buttons grid, there are 4 others as this one-->
<Grid Grid.Column="0" Grid.Row="1" BackgroundColor="Gray">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Source="comochegarbtn.png" HorizontalOptions="FillAndExpand" Grid.Row="0" Grid.Column="0">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="MapaClique"/>
</Image.GestureRecognizers>
</Image>
<StackLayout Grid.Row="0" Grid.Column="0" HorizontalOptions="Center" VerticalOptions="Center">
<Image Source="Location.png" VerticalOptions="FillAndExpand"/>
<Label Text="Como Chegar" TextColor="White" HorizontalOptions="Center" Style="{Binding labelsfont}"/>
</StackLayout>
</Grid>
</Grid>
In android I could solve that using wrap_content
But here, in xamarin forms, I don't know how to solve it
The gray part is the grid item size
If you need the exact size of the Text to be the width of your Image then you will have to use RelativeLayout.
In the RelativeLayout for the Image width use RelativeToView.
This is similar to the Relative Layout in Android.
<RelativeLayout>
<Image RelativeLayout.WidthConstraint="{ConstraintExpression Type=Type=RelativeToView, ElementName=myStacklayout,Property=Width,Factor=1}" Source="comochegarbtn.png" HorizontalOptions="FillAndExpand" Grid.Row="0" Grid.Column="0">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="MapaClique"/>
</Image.GestureRecognizers>
</Image>
<StackLayout x:Name="myStacklayout" HorizontalOptions="Center" VerticalOptions="Center">
<Image Source="Location.png" VerticalOptions="FillAndExpand"/>
<Label Text="Como Chegar" TextColor="White" HorizontalOptions="Center" Style="{Binding labelsfont}"/>
</StackLayout>
</RelativeLayout>
Using one or 2 relative layouts won't affect you much. But if you think it does you can write a custom render and create a complex button in the native layer.
I want to know what would be a XAML windows phone "Border" to Xamarin Forms? there's no Border to use BorderThickness, i want to draw some "lines" and set inside of 5 row's.Thanks
XAML Windows Phone :
<Border Grid.Row="0" BorderThickness="0,0,0,2" BorderBrush="#fe98fe"/>
I found a Frame on xamarin it does almost the same thing as Border but is not looking good for me!
If you just want to draw a Line, you can use the BoxView https://developer.xamarin.com/api/type/Xamarin.Forms.BoxView/
Example for a horizontal line with height 2:
<BoxView Color="Red" HeightRequest="2" HorizontalOptions="FillAndExpand"></BoxView>
But there is currently no feature complete counterpart for Border.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<BoxView Grid.Row="0" BackgroundColor="Red" HeightRequest="2" VerticalOptions="End" HorizontalOptions="FillAndExpand"></BoxView>
<BoxView Grid.Row="1" BackgroundColor="Red" HeightRequest="2" VerticalOptions="End" HorizontalOptions="FillAndExpand"></BoxView>
<BoxView Grid.Row="2" BackgroundColor="Red" HeightRequest="2" VerticalOptions="End" HorizontalOptions="FillAndExpand"></BoxView>
<BoxView Grid.Row="3" BackgroundColor="Red" HeightRequest="2" VerticalOptions="End" HorizontalOptions="FillAndExpand"></BoxView>
</Grid>
I wouldn't do the same way as the accepted answer suggest.
The best thing to do (IMHO) is either to use a Frame or a Grid/StackLayout/AnyContainerHere.
Here is what I would do
<Grid BackgroundColor="YourBorderColorHere" Padding="YourBorderWidthValueWhichIsNotOfTypeThickness">
<YourContentHere [BackgroundColor="YourInnerBackgroundHere"]/>
<!-- If you don't have a content to set, use a BoxView with a different color (your background color)-->
</Grid>
This would do the same with less control, less rendering stuff so better perf.
If you want corner radius do the same thing with a Frame.
If the author didn't like the Frame appearance, he should had try to set on its Frame a CornerRadius to 0 and HasShadow to False.
The less control and content to render, the better !
I like to quote Van der Rohe : "Less is more"
If you just want to draw a Line (Border with Thickness = 0,0,0,2), use a BoxView.