Frank
Frank

Reputation: 3

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

Upvotes: 0

Views: 1189

Answers (2)

Frank
Frank

Reputation: 3

you're right, AbsolueLayout is hard to understand at the beginning, they almost drove me crazy. But after two hours I understood it with your examples. The crux of the docu is the first sentence: The values X and Y change the anchor within the element AND the surrounding view. In the attached picture you can (I think) understand this quite well. I continue to use the AbsoluteLayout now, because it allows me to implement all the planned layouts well. Many thanks for the mental boost.

enter image description here

Upvotes: 0

Junior Jiang
Junior Jiang

Reputation: 12723

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:

  • Elements cannot be positioned off screen using proportional values.
  • Elements can be reliably positioned along any side of the layout or in the center, regardless of the size of the layout or device.

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

Upvotes: 1

Related Questions