xamllistviewxamarinabsolutelayout

Positioning elements within a listview with xaml / xamarin


I would like to understand how to positioning elements within a listview (CustomCell) as this will be my main display element. But I have difficulties to use the AbsoluteLayout tag, maybe anyone could give some hints.

I'am using VisualStudio 2017 15.9, test it on the Android emulator (but don't think this is relevant)

I have an example from the internet what is running and in priciple I understand it. I play around with all ways to positioning the elements as wanted, but with no success.

  1. For example I would like to have the both labels always in the middle (x=50%) of the row, regardless of the size of the image. The AbsoluteLayout does not work as expected, maybe because it inside a StackLayout.

The labels are always directly after the image with a little gap.

  1. Additionally I would like to positioning the second label in the Yposition, so there is no gap between the first and the second label.

Actually the first label starts on y=0 and the second label is at about y=50% and so there is a gap between them.

Thanks for help, Frank

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="FormsListViewSample.MainViewXaml"
xmlns:local="clr-namespace:FormsListViewSample;assembly=FormsListViewSample"
Title="ListView Xaml Sample"
>
    <ContentPage.Content>
        <ListView  x:Name="lstView" RowHeight="50">
            <ListView.ItemTemplate>
                <DataTemplate>
          <ViewCell>
            <AbsoluteLayout>
              <StackLayout Orientation="Horizontal" >
                <Image Source="{Binding Image}"  BackgroundColor="Aqua"  />
                <StackLayout Orientation="Vertical"  BackgroundColor="Yellow" >

                  <Label BackgroundColor="Red" Text = "{Binding Name}" AbsoluteLayout.LayoutBounds="0.5, 0, 100, 30" AbsoluteLayout.LayoutFlags="PositionProportional"/>
                  <Label BackgroundColor="Blue" Text = "{Binding Type}" AbsoluteLayout.LayoutBounds="0.5, 0.4, 100, 30" AbsoluteLayout.LayoutFlags="PositionProportional"/>
                </StackLayout>

              </StackLayout>
            </AbsoluteLayout>
          </ViewCell>
        </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ContentPage.Content>
</ContentPage>

This is the actual results

This is what I would like to have


Solution

  • About AbsoluteLayout ,official document has a explain that:

    AbsoluteLayout has a unique anchor model whereby the anchor of the element is positioned relative to its element as the element is positioned relative to the layout when proportional positioning is used. When absolute positioning is used, the anchor is at (0,0) within the view. This has two important consequences:

    AbsoluteLayout, like RelativeLayout, is able to position elements so that they overlap.

    Note in the shared link, the anchor of the box is a white dot. Notice the relationship between the anchor and the box as it moves through the layout.

    Maybe this seems to be difficult to understand, but AbsoluteLayout is like this.Here is a sample code about how Anchor works in AbsoluteLayout.

    <AbsoluteLayout HeightRequest="200"  BackgroundColor="Yellow">  
        <Label BackgroundColor="YellowGreen" Text = "labeone1"    AbsoluteLayout.LayoutBounds="0, 0, 0.5, 0.09"     AbsoluteLayout.LayoutFlags="All"/>
        <Label BackgroundColor="Red"         Text = "labetwo2"    AbsoluteLayout.LayoutBounds="0.1, 0.1, 0.5, 0.09" AbsoluteLayout.LayoutFlags="All"/>
        <Label BackgroundColor="Blue"        Text = "labethree3"  AbsoluteLayout.LayoutBounds="0.2, 0.2, 0.5, 0.09" AbsoluteLayout.LayoutFlags="All"/>
        <Label BackgroundColor="White"       Text = "labefour4"   AbsoluteLayout.LayoutBounds="0.3, 0.3, 0.5, 0.09" AbsoluteLayout.LayoutFlags="All"/>
        <Label BackgroundColor="Gray"        Text = "labefive5"   AbsoluteLayout.LayoutBounds="0.4, 0.4, 0.5, 0.09" AbsoluteLayout.LayoutFlags="All"/>
        <Label BackgroundColor="Green"       Text = "labesix6"    AbsoluteLayout.LayoutBounds="0.5, 0.5, 0.5, 0.09" AbsoluteLayout.LayoutFlags="All"/>
        <Label BackgroundColor="BlueViolet"  Text = "labeseven7"  AbsoluteLayout.LayoutBounds="0.6, 0.6, 0.5, 0.09" AbsoluteLayout.LayoutFlags="All"/>
        <Label BackgroundColor="AliceBlue"   Text = "labeeight8"  AbsoluteLayout.LayoutBounds="0.7, 0.7, 0.5, 0.09" AbsoluteLayout.LayoutFlags="All"/>
        <Label BackgroundColor="BlueViolet"  Text = "labenine9"   AbsoluteLayout.LayoutBounds="0.8, 0.8, 0.5, 0.09" AbsoluteLayout.LayoutFlags="All"/>
        <Label BackgroundColor="DarkSlateGray" Text = "labeten10" AbsoluteLayout.LayoutBounds="0.9,0.9, 0.5, 0.09"  AbsoluteLayout.LayoutFlags="All"/>
        <Label BackgroundColor="Orange"     Text = "labeeleven11" AbsoluteLayout.LayoutBounds="1, 1, 0.5, 0.09"     AbsoluteLayout.LayoutFlags="All"/>
        <Label BackgroundColor="OrangeRed"  Text = "labeeleven12" AbsoluteLayout.LayoutBounds="1.1, 1.1, 0.5, 0.09" AbsoluteLayout.LayoutFlags="All"/>
    </AbsoluteLayout>
    

    enter image description here

    If using AbsoluteLayout like this , it will work:

    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell> 
           <StackLayout HeightRequest="50" Padding="10">
              <AbsoluteLayout>
                 <Image Source="{Binding ImageUrl}"  BackgroundColor="Aqua"   AbsoluteLayout.LayoutBounds="0, 0, 0.5, 1" AbsoluteLayout.LayoutFlags="All"/>
                 <Label BackgroundColor="Red" Text = "{Binding Name}" AbsoluteLayout.LayoutBounds="1, 0, 0.5, 0.5" AbsoluteLayout.LayoutFlags="All"/>
                 <Label BackgroundColor="Blue" Text = "{Binding Location}" AbsoluteLayout.LayoutBounds="1, 1, 0.5, 0.5" AbsoluteLayout.LayoutFlags="All"/>
              </AbsoluteLayout>
           </StackLayout>
         </ViewCell>
       </DataTemplate>
    </ListView.ItemTemplate>
    

    enter image description here

    Here AbsoluteLayout is not the best solution to achieve what you want, you can try using the Grid layout in ViewCell as follows:

    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell> 
           <Grid Padding="10,10,10,10">
               <Grid.RowDefinitions>
                  <RowDefinition Height="25"></RowDefinition>
                  <RowDefinition Height="25"></RowDefinition>
               </Grid.RowDefinitions>
               <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="50*"></ColumnDefinition>
                  <ColumnDefinition Width="50*"></ColumnDefinition>
               </Grid.ColumnDefinitions>
    
               <Image Grid.Column="0" Grid.RowSpan="2" Source="{Binding Location}" BackgroundColor="Accent"/>
               <Label  Grid.Row="0" Grid.Column="1" Text="{Binding Name}" BackgroundColor="Red" TextColor="White" FontSize="Large" HorizontalOptions="Start" VerticalOptions="Center"></Label>
               <Label Grid.Row="1" Grid.Column="1" Text="{Binding Type}" BackgroundColor="Green" TextColor="White" FontSize="Large" HorizontalOptions="Start" VerticalOptions="Center"></Label>
            </Grid>
         </ViewCell>
       </DataTemplate>
    </ListView.ItemTemplate>
    

    enter image description here