Xamarin forms listview - show images full widh, auto height - xamarin

I have a listview in Xamarin Forms and I have a requirement to maintain aspect ratio but also this:
When an image is taller than it is wide, show the image flush to the left and right with no margins, have the height be auto
When an image is wider than it is tall, the requirement is the same, but this works. In the screenshot it shows how images currently render when they're taller than wide. Changing the aspect property breaks the condition when it is wider than tall. When I copy this template into a blank page, the image displays fine. I think the issue is being able to set the height of each row in the listview to auto. It may not be the issue though. I'm using a SyncFusion listview for Xamarin
Here is the code for the item template of the listview:
<DataTemplate>
<ViewCell>
<StackLayout Margin="0,10,0,10" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<!-- Card Header -->
<!-- Truncated for brevity -->
</Grid>
<StackLayout Grid.Row="1">
<!-- Card title -->
<!-- Truncated for brevity -->
</StackLayout>
<!-- Card Body -->
<StackLayout BindingContextChanged="PostImageStackLayout_BindingContextChanged">
<Grid Grid.Row="2" x:Name="postImageStackLayout" Margin="0,15,0,10">
<!-- Card article image -->
<ffimageloading:CachedImage Grid.Row="0" x:Name="postImage" CacheDuration="1" HeightRequest="300"
Source="{Binding MainIMageURL}" BindingContextChanged="PostImage_BindingContextChanged"
VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
Margin="0,10,0,10" FadeAnimationEnabled="True" Aspect="AspectFit" >
<ffimageloading:CachedImage.GestureRecognizers>
<TapGestureRecognizer Tapped="PostImageTapped" CommandParameter="{Binding }"/>
</ffimageloading:CachedImage.GestureRecognizers>
</ffimageloading:CachedImage>
</Grid>
</StackLayout>
<!--Likes and comment count-->
<!-- Truncated for brevity -->

Don't put fix height on Grid Row where it have the image element. You can use the "auto" value.
<RowDefinition Height="auto"/>
and change the Aspect to
AspectFill
I use the collectionview from the latest Xamarin.Forms 4.3. Here is my sample code
xaml
<ContentView.Content>
<StackLayout>
<CollectionView x:Name="ImagesCollectionView">
<CollectionView.ItemsLayout>
<ListItemsLayout ItemSpacing="20">
<x:Arguments>
<ItemsLayoutOrientation>Vertical</ItemsLayoutOrientation>
</x:Arguments>
</ListItemsLayout>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<ffimageloading:CachedImage
HorizontalOptions="FillAndExpand"
Source="{Binding .}"
Aspect="AspectFill"
LoadingPlaceholder="noimg.png"/>
<Label Text="label"
TextColor="Gray"
Opacity="0.8"
Margin="12,0,0,0"
HorizontalOptions="Start"
FontSize="Small"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentView.Content>
c#
public MySecondView()
{
InitializeComponent();
ImagesCollectionView.ItemsSource = new List<string>()
{
"http://insidetema.com/wp-content/uploads/2018/05/170717100550_1_900x600.jpg"
,"https://informationng.com/wp-content/uploads/2014/03/bigstock_Happy_Business_People_With_Han_4049346.jpg"
,"http://www.blt.co.uk/wp-content/uploads/2018/03/Happy-Places.jpg"
};
}
Output

You can set the HeightRequest and WidthRequest of your image to -1 (then it'll fit all the space available)

Related

Xamarin Forms Grid.Row Auto --> Still Shows Scrollbar in Grid Item

I have a slight problem with XamarinForms, which I am fairly new with.
I do have a grid with several Items in it (ListView, Label, Stacklayout, Listview).
I thought setting RowDefinitions = "Auto" for each row, would make the whole Page scrollable.
But instead I have a scrollbar on each individual listView.
I have added a snippet of my code with one of the listViews inside.
How do I get the listViews shown in their full size and the scrollbar be for the whole page?
I have already tried a scrollview instead of the grid, but it did not work.
Picture of Content in Emulator
Picture of Whole Page
Xamarin Forms:
<Grid
Padding="10"
RowDefinitions="Auto,Auto,Auto,Auto"
ColumnDefinitions="*"
>
<Label Padding="20" FontAttributes="Bold" FontSize="40" Text="{Binding DisplayName}" Grid.Row="0"/>
<ListView ItemsSource="{Binding News}"
HasUnevenRows="True"
IsPullToRefreshEnabled="False"
Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10">
<Label Text="{Binding DateTimeString}"/>
<Label Text="{Binding Text}" MaxLines="4"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Header>
<Grid ColumnDefinitions="*,Auto"
Padding="10"
VerticalOptions="Center">
<Label Text="News"
Grid.Column="0"
FontAttributes="Bold"
FontSize="32"/>
<Label Text="mehr Anzeigen"
Grid.Column="1"
HorizontalTextAlignment="End"/>
</Grid>
</ListView.Header>
</ListView>
You can put the items in ScrollView which is capable of scrolling its content.
refer to: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/scrollview

Xamarin form carouselview scrolls with multiple items for single scroll

Iam using Carousel view control available in Xamarin form(Version 5).
In my case i used Listviews inside carousel view. It works fine if scroll by swiping to left or right, but if i programmatically set the ScrollTo or Position property for the carousel view using button click then it is scrolling multiple times though i'm setting single incremental value.
I added SnapPointsType="MandatorySingle" as mentioned here
One more issue is if my current carousel position is zero and moving to last position or more then one is not working.
<AbsoluteLayout Margin="2" BackgroundColor="Transparent">
<CarouselView
x:Name="MyCarousalView"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
Scrolled="CarouselViewScrolled">
<CarouselView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" ItemSpacing="0" SnapPointsType="MandatorySingle" />
</CarouselView.ItemsLayout>
<CarouselView.ItemTemplate>
<DataTemplate>
<ListView
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
ItemsSource="{Binding .}"
x:FieldModifier="public">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Tapped="ViewCellTapped">
<StackLayout Padding="0">
<StackLayout Padding="20,1" VerticalOptions="StartAndExpand" Spacing="0" >
<Label
FontSize="16"
Text="{Binding Description}"
FontAttributes="Bold"/>
<Label
FontSize="14"
Text="{Binding CreatedDate}" />
</StackLayout>
<Label HorizontalOptions="FillAndExpand" Padding="0" HeightRequest="1" BackgroundColor="#D4D4D4"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</AbsoluteLayout>
Next button click event
private void NextClicked(object sender, EventArgs e)
{
MyCarousalView.ScrollTo((MyCarousalView.Position + 1) < _weekDaysList.Count ? MyCarousalView.Position + 1 : 0);
}
Carousel view binding:
List<List<Note>> _myList;
_myList=getData(); //based on service response
MyCarousalView.ItemsSource = null;
MyCarousalView.ItemsSource = _myList;
Screen recording with issue image
Screen video
Please letme know if any solution/workaround. Thanks

Transparency not rendering the same on xamarin.ios project

I just can't understand why the background for my side menu on xamarin forms won't render the same on my xamarin.ios. Yet in other parts of the project my list views render and look the same when I use transparent backgrounds, I even tried copying and pasting the xaml code from other parts of the project where it does render the same, but still it does not work. In case anyone's wondering the side menu on ios was requested by the client.
Attached below I have 2 images showing how the side menu renders differently on the 2 platforms
Here's the Xaml code I'm using for my Side Menu:
<MasterDetailPage.Master>
<StackLayout Orientation="Vertical" BackgroundColor="Transparent" Spacing="0">
<StackLayout
HorizontalOptions="Fill"
Orientation="Horizontal"
VerticalOptions="Fill" BackgroundColor="Black" Padding="50, 50, 50, 50">
<StackLayout HorizontalOptions="Center" Orientation="Vertical">
<ffimageloading:CachedImage x:Name="ProfilePictureCircleImage"
LoadingPlaceholder="profile_image_placeholder.png"
ErrorPlaceholder="profile_image_placeholder.png"
DownsampleToViewSize="true"
FadeAnimationEnabled="true"
HeightRequest="65"
WidthRequest="65">
<ffimageloading:CachedImage.Transformations>
<fftransformations:CircleTransformation/>
</ffimageloading:CachedImage.Transformations>
</ffimageloading:CachedImage>
</StackLayout>
<StackLayout
HorizontalOptions="CenterAndExpand"
Orientation="Vertical"
VerticalOptions="CenterAndExpand">
<Label
x:Name="FullNameLabel"
FontSize="18"
HorizontalOptions="Center"
TextColor="White"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</StackLayout>
<BoxView HeightRequest="2" BackgroundColor="#D90B31"/>
<ListView
x:Name="NavigationMenuItems"
ItemSelected="OnMenuItemSelected"
BackgroundColor="{StaticResource TileColour}"
RowHeight="60"
SeparatorVisibility="None"
SeparatorColor="Transparent">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<!-- Main design for menu items -->
<StackLayout
Padding="20,10,0,10"
Orientation="Horizontal"
Spacing="20"
VerticalOptions="FillAndExpand"
BackgroundColor="Transparent">
<local:TintedCachedImage TintColor="{StaticResource SideMenuIconColor}"
Source="{Binding Icon}"
VerticalOptions="Center"
DownsampleToViewSize="true"
HeightRequest="19"
WidthRequest="19"/>
<Label
FontSize="15"
Text="{Binding Title}"
TextColor="{StaticResource SideMenuTextColor}"
VerticalOptions="Center" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage />
</MasterDetailPage.Detail>
above are pictures illustrating how it looks across the 2 platforms.
Found the solution to this question on another stackoverflow thread I had to use a custom renderer:
public class CustomSideMenuRenderer: TabletMasterDetailRenderer
{
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
var master = ViewControllers[0];
master.View.BackgroundColor = UIColor.Clear;
var detail = ViewController.ChildViewControllers[1];
}
}

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?

Disable Xamarin Form and Show Activity Indicator

I have a Xamarin Form which is using Scroll View.
I am trying to show a Activity Indicator at the top as I have a ListView in the middle.
But when the user scrolls down the loading is not shown.
So, I need help in disabling the page and showing loading at some z-index as in a popup.
If you want to have an overlay while the screen is loading you can do this.
<Grid>
<ScrollView>
<!-- Insert your page content in here -->
</ScrollView>
<ContentView IsVisible="false" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<ActivityIndicator IsRunning="false" />
</ContentView>
</Grid>
When you set your ContentView to IsVisible="true" it will then overlay on top of your page. You can set the background color and opacity on the ContentView if needed to provide a grey out effect.
Or you can use a similar method and have
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ActivityIndicator Grid.Row="0" />
<ScrollView Grid.Row="1">
</ScrollView>
</Grid>
In this way you will have the activity indicator above the scroll view at all times and allow the user to still scroll.
I am new to the Xamarin but you do as below.
<Grid IsEnabled="{Binding IsBusy,Converter={converters:InverseBoolConverter}}" >
...
<ActivityIndicator
Color="{StaticResource LightGreenColor}"
IsRunning="{Binding IsBusy}"
IsVisible="{Binding IsBusy}"
VerticalOptions="Center"
HorizontalOptions="Center">
<ActivityIndicator.WidthRequest>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="iOS, Android" Value="100" />
<On Platform="UWP, WinRT, WinPhone" Value="400" />
</OnPlatform>
</ActivityIndicator.WidthRequest>
</ActivityIndicator>
</Grid>

Resources