How to adjust my listview in ios Xamarin forms - xamarin

I have a problem in my ListView on iOS. I can't adjust it to all iOS templates, ex: put HeightRequest = "855" on my iPhone 7 it already fits correctly, else on the iPhone 5 and smaller my ListView from a scrow. so I want my ListView to automatically adjust to the screen size.
<ListView x:Name="listView"
CachingStrategy="RecycleElement"
ItemsSource="{Binding FeedItems}"
HasUnevenRows="True"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1" HeightRequest="855">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackLayout HeightRequest = "60" WidthRequest="60">
<Image x:Name="Image" Source="{Binding Image}" Scale="1.0" Aspect="AspectFill" VerticalOptions="FillAndExpand"/>
</StackLayout>
<StackLayout Grid.Column="2" Spacing="4" VerticalOptions="Center">
<Label Text="{Binding Category}" TextColor="White" FontSize="Small" LineBreakMode="NoWrap" BackgroundColor="{Binding Color_category}"/>
<Label Text="{Binding PublishDate}" TextColor="#666666" FontSize="Small" LineBreakMode="NoWrap"/>
<Label Text="{Binding Title}" TextColor="#234084" Font="Bold" FontSize="Small" LineBreakMode="WordWrap"/>
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

To expand a little more.
HeightRequest is used when you want to define a fixed size to an element. Xamarin will make its best to fulfill with this. In the other hand when you want your size to be relative you use the VerticalOptions and HorizontalOptions. This two properties will take a LayoutOptions struct and the default value for this is Fill (without expand).
This struct has two sets of properties, the ones I call "regular"
Center
Start
End
Fll
And the ones that "expands"
CenterAndExpand
StartAndExpand
EndAndExpand
FillAndExpand
You can read more about these here.
This last one FillAndExpand will take all the available space in the orientation it's used. This is the one you should use in your ListView to make it as big as the screen
Hope this helps.-

Related

How to make the BindableLayout to be scrollable

I have one list and i don't want to use listview inside it as how can i make it scrollable, data is binding but i am not able to scroll it.
<Grid Grid.Row="0" IsVisible="{Binding SearchListLayout}" Margin="0" Padding="0" BackgroundColor="White">
<ScrollView>
<StackLayout BindableLayout.ItemsSource="{Binding ProductsList}" x:Name="SearchLayoutItemList" HeightRequest="255">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Grid RowDefinitions="37,Auto">
<Image Grid.Row="0" Source="searchingicon.png" Style="{DynamicResource icons}"/>
<Label Grid.Row="0" Text="{Binding name}" FontSize="14" TextColor="Black" Margin="50,0,0,0" HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand"/>
<Image Grid.Row="0" Source="reload.png" Style="{DynamicResource icons}" HorizontalOptions="EndAndExpand" Margin="0,0,15,0"/>
<BoxView Grid.Row="1" Style="{DynamicResource DarkSeparator}" />
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
</Grid>
Although the BindableLayout technically can display your list of items via the StackLayout, and the StackLayout height is being restraint to your height request; the encompassing ScrollViewer has nothing to scroll since it fully contains your StackLayout.
To achieve what you probably want (a fixed 255 pixel StackLayout that scrolls your items) the ScrollViewer should be inside the StackLayout as the rendered ItemsPanel for you Items. Again, you could achieve this with custom BindableLayouts, but this is exactly what Xamarin Forms ListView does by default.
You probably simply want to change your BindableLayout implementation to a ListView:
<Grid Grid.Row="0" IsVisible="{Binding SearchListLayout}" Margin="0" Padding="0" BackgroundColor="White">
<ListView ItemsSource="{Binding ProductsList}" x:Name="SearchLayoutItemList" HeightRequest="255">
<ListView.ItemTemplate>
<DataTemplate>
<Grid RowDefinitions="37,Auto">
<Image Grid.Row="0" Source="searchingicon.png" Style="{DynamicResource icons}"/>
<Label Grid.Row="0" Text="{Binding name}" FontSize="14" TextColor="Black" Margin="50,0,0,0" HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand"/>
<Image Grid.Row="0" Source="reload.png" Style="{DynamicResource icons}" HorizontalOptions="EndAndExpand" Margin="0,0,15,0"/>
<BoxView Grid.Row="1" Style="{DynamicResource DarkSeparator}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
The scrollview could not scroll as you set the HeightRequest="255" for the stacklayout in the scrollview. That because the display content's height is equal with the Scrollview, left content was covered.
Then I remove the HeightRequest
in StackLayout, the ScrollView could scroll. But the scrollview will fill the whole page which I thought is not what you want. So you could add parent layout Stacklayout outside the scrollview which set the size of scrollview equal to 255 and let it scroll at the same time. I just made an example :
<StackLayout>
<ScrollView HeightRequest="255">
<StackLayout BindableLayout.ItemsSource="{Binding ItemCollection}" x:Name="SearchLayoutItemList" >
<BindableLayout.ItemTemplate>
<DataTemplate>
<Grid RowDefinitions="37,Auto">
<Image Grid.Row="0" Source=""searchingicon.png"" />
<Label Grid.Row="0" Text="{Binding name}" FontSize="14" TextColor="Black" Margin="50,0,0,0" HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand"/>
<Image Grid.Row="0" Source="reload.png" HorizontalOptions="EndAndExpand" Margin="0,0,15,0"/>
<BoxView Grid.Row="1" BackgroundColor="Yellow"/>
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
</StackLayout>
For more info, you could refer to Xamarin.Forms ScrollView.
Hope it works for you.

How can I move the relative position of an image in a grid?

I am creating a car app that lists cars and their prices, model, speed, etc. I wanted to position the price over an image of the car, like so:
To do this, I created a grid and allowed the image to fill the entire thing while forcing the text (with a frame around it) into a lower column/row. However, I am ending up with white space on the top of the graph. Take a look. I set the grid to a background color of blue for easier viewing.
The issue here is the aspect ratio, because an image that did fill the entire grid would cut off the sides. The size of the whitespace is equivalent to the overlay, so if I had the overlay any lower that would result in more whitespace on both sides.
Note: Some of the cars have different aspect ratios, so this has to be a fix that would work for other images as well.
Note 2: This has to be a relative position fix, since obvious methods like setting the image's margin to -100 wouldn't work on other resolution screens and would probably get me fired.
The question: How can I relatively (e.g. make it work on every screen) force the image to the top of the page while still keeping the same aspect ratio and keeping the overlay?
Here's the front-end.
<StackLayout>
<!-- Image and cost grid-->
<Grid BackgroundColor="Blue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="63*"/>
<ColumnDefinition Width="35*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="75*"/>
<RowDefinition Height="25*"/>
</Grid.RowDefinitions>
<Image Source="{Binding ImageLocation}" Grid.ColumnSpan="3" Grid.RowSpan="2"/>
<Frame BackgroundColor="White" CornerRadius="5" Grid.Column="1" Grid.Row="1">
<Label Text="{Binding Cost}" FontSize="Large" HorizontalTextAlignment="End" TextColor="Black"/>
</Frame>
</Grid>
<!-- Information about the car -->
<StackLayout Padding="15">
<Label Text="{Binding Company}" FontSize="Large"/>
<Label Text="{Binding Model}" FontSize="Medium" FontAttributes="Bold"/>
</StackLayout>
</StackLayout>
Move your frame not the image.
Set Grid content in one row.
Set Frame VerticalOptions to End
Set Frame HeightRequest and Margin (minus value).
Set bottom StackLayout VerticalOptions to FillAndExpand
<StackLayout>
<!-- Image and cost grid-->
<Grid BackgroundColor="Blue" ColumnDefinitions="63*, 35*, 2*">
<Image Source="{Binding ImageLocation}" Grid.ColumnSpan="3"/>
<!-- Shape the Frame here -->
<Frame HeightRequest="40" Margin="0,0,0,-20" VerticalOptions="End"
BackgroundColor="White" CornerRadius="5" Grid.Column="1" >
<Label Text="{Binding Cost}" FontSize="Large" HorizontalTextAlignment="End" TextColor="Black"/>
</Frame>
</Grid>
<!-- Information about the car -->
<StackLayout Padding="15" VerticalOptions="FillAndExpand">
<Label Text="{Binding Company}" FontSize="Large"/>
<Label Text="{Binding Model}" FontSize="Medium" FontAttributes="Bold"/>
</StackLayout>
</StackLayout>

Customise ListView using Xamarin Forms

Is it possible to create a `ListView' like the attached screen shot using Xamarin Forms.
Try this:
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding image}" WidthRequest="50" HeightRequest="50" Grid.Column="0" VerticalOptions="Center"/>
<StackLayout Grid.Column="1">
<Label Text="{Binding property1}" TextColor="#f35e20" HorizontalTextAlignment="Center"/>
</StackLayout>
<StackLayout Grid.Column="2">
<Label Text="{Binding property2}" HorizontalTextAlignment="Center" TextColor="#503026"/>
</StackLayout>
<StackLayout Grid.Column="3">
<Label Text="{Binding property3}" HorizontalTextAlignment"Center" TextColor="#503026"/>
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You can use https://github.com/jamesmontemagno/ImageCirclePlugin to create circular image for the first column.
To design something like this, you can take a Grid layout with 1 row and 4 column.
In 1st column: you can draw shape like this:How To Draw a circle with a text in the center using Xamarin Forms C# Without using custom-renderer?
<Frame HeightRequest="40" WidthRequest="40" CornerRadius="20" HorizontalOptions="Start" VerticalOptions="Start" Margin="0" Padding="0" BackgroundColor="Maroon">
<Label Text="7" TextColor="White" HorizontalOptions="Center" VerticalOptions="Center" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
In other columns, you can have Stacklayout with padding 1 and BackgroundColor black applied in it, containing Label with BackgroundColor Blue and text in it.
Hope this may solve your issue.

AutoScale Label Xamarin

I am working on an app that displays results from a RSS feed. I am trying to show the Title and the Date in the same row of a Stacklayout.
Xaml Code:
StackLayout>
<Label Text="60 Second Sports" FontAttributes="Bold" HorizontalOptions="Center"/>
<ListView x:Name="mainArticleRssList" IsPullToRefreshEnabled="True" Refreshing="ListItems_Refreshing" ItemTapped="RssList_ItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="15,0,15,0">
<Label Text="{Binding Title}"
LineBreakMode="WordWrap"
MaxLines="2"/>
<Label Text="{Binding PublishedDate}"
LineBreakMode="WordWrap"
MaxLines="1"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<controls:AdMobView />
</StackLayout>
Here is what it looks like:
What I Expect:
I want the Title to auto scale to fit in the same row as the date. Is it possible to set a width for the entire row and then have the two labels fit inside of the row?
Other fruits of a few hours of googling:
Here are some of the links I found, but some are old and not sure if they work.
This one is old Auto Scale Text Size
This one didn't work Auto-scaling label fontsize in Xamarin
I also found a couple Nuget packages, but i don't think i need to do that.
https://baskren.github.io/Forms9Patch/
https://forums.xamarin.com/discussion/43468/autosize-font-label
Use Grid Layout inside stack layout to achive it
<ListView x:Name="mainArticleRssList" IsPullToRefreshEnabled="True" HasUnevenRows="True" Refreshing="ListItems_Refreshing" ItemTapped="RssList_ItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="15,0,15,0">
<Grid x:Name="grd">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding Title}"
LineBreakMode="WordWrap"
MaxLines="2"/>
<Label Text="{Binding PublishedDate}" Grid.Column="1"
LineBreakMode="WordWrap"
MaxLines="1"/>
</Grid>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Use this code and it will work for you.
Is that your needs like this screenshot?
You can use Grid to achieved that.
<ContentPage.Content>
<StackLayout>
<Label Text="Xamarin.Forms native cell" HorizontalTextAlignment="Center" />
<ListView x:Name="listView" CachingStrategy="RecycleElement"
ItemSelected="OnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Title}" Grid.Row="0" Grid.Column="0"
LineBreakMode="TailTruncation"
MaxLines="2" />
<Label Text="{Binding PublishedDate}" Grid.Row="0" Grid.Column="1"
LineBreakMode="WordWrap"
MaxLines="1"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
If title is too long, you can setLineBreakMode="TailTruncation" it will automatically truncate when the label reaches the end of the container.

Xamarin.Forms: how to set Images to get the expected result

I'm looking for a good way to implement a control that looks like a ListView with 2 columns, where each column has distinct height. As I didn't found another solution, I've decided to do it through a Repeater control.
The expected result is something like this:
All the items come from the same DataSource, and this DataSource will contain between one and a dozen of items.
The items must be splitted automatically (by modulo) into the 2 columns
When the user click on the button related to the item, this will open the item's detail page
The red squares are images that must have the same height/width
I'm working on the design of the cell DataTemplate, but I didn't see how to manage the images:
The distinction between the 2 columns is given by a Grid containing 2 Columns
Then I specify the DataTemplate for each column
<ScrollView>
<Grid Padding="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Col.1 -->
<tabletControls:Repeater Grid.Column="0" Margin="10"
ItemsSource="{Binding ListProductItems}">
<tabletControls:Repeater.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" >
<StackLayout>
<ffimageloading:CachedImage Source="{Binding Icon}"
Aspect="AspectFill"/>
</StackLayout>
...
</StackLayout>
</ViewCell>
</DataTemplate>
</tabletControls:Repeater.ItemTemplate>
</tabletControls:Repeater>
<!-- Col.2 -->
<tabletControls:Repeater Grid.Column="1" Margin="10"
ItemsSource="{Binding ListProductItems}">
<tabletControls:Repeater.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" >
<StackLayout>
<ffimageloading:CachedImage Source="{Binding Icon}"
Aspect="AspectFill"/>
</StackLayout>
...
</StackLayout>
</ViewCell>
</DataTemplate>
</tabletControls:Repeater.ItemTemplate>
</tabletControls:Repeater>
</Grid>
</ScrollView
But this doesn't work as expected, as the image's height/width are not the same:
I already tried to play with Aspect (AspectFill, AspectFit, Fill) or VerticalOptions/HorizontalOptions, withou any result...
Is it possible to achieve the expected result without specify an HeightRequest? Are there other options?

Resources