Customise ListView using Xamarin Forms - xamarin

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.

Related

Xamarin Forms 2.X - ListView with Grid how to call API for each Row that is inserted into my grid rows

I have the following Xamarin forms grid.
<ListView x:Name="liewViewData" ItemsSource="{Binding InfoList}" ItemAppearing="OnItemApprearing" ItemSelected="OnItemSelected" RowHeight="{Binding ListViewRowHeight}">
<ListView.Header>
<StackLayout Padding="10,5,0,5" BackgroundColor="#cccccc">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.8*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="" VerticalTextAlignment="Center" HorizontalTextAlignment="Start" FontSize="Small" />
<Label Grid.Column="1" Text="Demo" VerticalTextAlignment="Center" FontSize="Small" />
</Grid>
</StackLayout>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.8*" />
</Grid.ColumnDefinitions>
<Image Source="danger.png" Grid.Column="0" BackgroundColor="Transparent" HorizontalOptions="Center" VerticalOptions="Center"></Image>
<Label Grid.Column="1" Text="{Binding Name}" VerticalTextAlignment="Center" FontSize="Small" />
</Grid>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
What I need is that on the ItemAppearing event for each grid row added I call an API and update the row data such as the image etc.
Any clue on how to do this?
You need to data bind the image, implement OnPropertyChanged for that field and assign value to it in the event that you mention. Not sure which part you were missing, but as simple as that.

How to show group and grouped items within a frame Xamarin.Forms

Has anyone implanted something like the following, that could be of relevance to me? How can I put a frame that encompasses both the group and the items in the photo:
click to enlarge
I have a dirty but simple way:
When I make same forms I use ListView without grouping and ViewCell with RepeaterView. You need remember that it is not the best perfomance way.
If you want to design the UI like the screenshot your provided, using frame to crop image, you can take a look:
<CollectionView IsGrouped="true" ItemsSource="{Binding Animals}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Frame Padding="0"
Grid.RowSpan="2"
BorderColor="Black"
CornerRadius="50"
HeightRequest="40"
HorizontalOptions="Center"
IsClippedToBounds="True"
WidthRequest="40">
<Image
Aspect="AspectFill"
HeightRequest="100"
Source="{Binding ImageUrl}"
WidthRequest="100" />
</Frame>
<Label
Grid.Column="1"
FontAttributes="Bold"
Text="{Binding Name}" />
<Label
Grid.Row="1"
Grid.Column="1"
FontAttributes="Italic"
Text="{Binding Location}"
VerticalOptions="End" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<Label
BackgroundColor="LightGray"
FontAttributes="Bold"
FontSize="Large"
Text="{Binding Name}" />
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
</CollectionView>
About viewmodel class, you can take a look Xamarin.Forms CollectionView Grouping

How to Center an image in each column inside one row in Xamarin forms?

I know I have already asked this question here: How to Center an image in each column inside one row in Xamarin?, but I didnt have access to an actual device that time, so I just run the emulator and it looks like this:
But now that I have a phone to run it, the page now looks like this:
This is my code for this page:
<StackLayout>
<RelativeLayout>
<Grid Margin="0,10,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<StackLayout Grid.Row="0" Grid.Column="0" HorizontalOptions="CenterAndExpand">
<Image x:Name="ImgSrcMale"
HeightRequest="165"
Source="male"
WidthRequest="200"
Aspect="AspectFit"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand">
<Image.GestureRecognizers>
<TapGestureRecognizer x:Name="MaleClick"
NumberOfTapsRequired="1"
Tapped="MaleClick_Tapped"/>
</Image.GestureRecognizers>
</Image>
</StackLayout>
<StackLayout Grid.Row="0" Grid.Column="1" HorizontalOptions="CenterAndExpand">
<Image Source="female1"
WidthRequest ="200"
HeightRequest="165"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"
Aspect="AspectFit"
x:Name="ImgSrcFemale">
<Image.GestureRecognizers>
<TapGestureRecognizer x:Name="FemaleClick"
NumberOfTapsRequired="1"
Tapped="FemaleClick_Tapped"/>
</Image.GestureRecognizers>
</Image>
</StackLayout>
</Grid>
<Grid Margin="0,178,0,0">
<ScrollView>
<StackLayout>
<Grid VerticalOptions="CenterAndExpand" Margin="20,0,20,0" RowSpacing="20">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Text="Gender"
FontSize="Title"
TextColor="WhiteSmoke"
HorizontalOptions="Center"
FontAttributes = "Bold"
Grid.Row="0"/>
<local:RoundedEntry x:Name="EntryUsername"
Placeholder="Username"
TextColor="WhiteSmoke"
PlaceholderColor="WhiteSmoke"
Grid.Row="1"/>
<local:RoundedEntry x:Name="EntryPassword"
Placeholder="Password"
IsPassword="True"
TextColor="WhiteSmoke"
PlaceholderColor="WhiteSmoke"
Grid.Row="2"/>
<local:RoundedEntry x:Name="EntryEmail"
Placeholder="Email"
Keyboard="Email"
TextColor="WhiteSmoke"
PlaceholderColor="WhiteSmoke"
Grid.Row="3"/>
<Button Text="Sign Up"
HorizontalOptions="CenterAndExpand"
TextColor="WhiteSmoke"
BackgroundColor="Coral"
WidthRequest="150"
Clicked="Button_Clicked"
CornerRadius="25"
FontAttributes = "Bold"
FontSize = "Large"
Grid.Row="4"/>
<Label x:Name="GenderLabel"
Text=""
TextColor="WhiteSmoke"
IsVisible="False"/>
</Grid>
</StackLayout>
</ScrollView>
</Grid>
</RelativeLayout>
</StackLayout>
You could easily create this layout with one grid. Remove the top-level StackLayout and RelativeLayout. You may want to put the whole grid inside a scrollview to allow the screen to move up with the keyboard.
I'd recommend a grid with two columns and six rows (the controls at the bottom will span both columns. Define the columns with width * (not sure why you had 5*). You don't need to wrap the images in anything, just place them in the grid directly.

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.

How to adjust my listview in ios Xamarin forms

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.-

Resources