使用 xaml / xamarin 在列表视图中定位元素

Positioning elements within a listview with xaml / xamarin

我想了解如何在列表视图 (CustomCell) 中定位元素,因为这将是我的主要显示元素。 但是我在使用AbsoluteLayout标签时遇到了困难,也许任何人都可以提供一些提示。

我正在使用 VisualStudio 2017 15.9,在 Android 模拟器上对其进行测试(但认为这无关紧要)

我有一个来自互联网的例子,什么是 运行,原则上我理解它。我尝试了各种方法来根据需要定位元素,但没有成功。

  1. 例如,无论图像大小如何,我都希望两个标签始终位于行的中间 (x=50%)。 AbsoluteLayout 没有按预期工作,可能是因为它位于 StackLayout 中。

标签总是紧跟在图像后面,中间有一点间隙。

  1. 此外,我想将第二个标签定位在 Y 位置,这样第一个和第二个标签之间就没有间隙了。

实际上第一个标签从 y=0 开始,第二个标签大约在 y=50% 处,因此它们之间存在间隙。

谢谢你的帮助,弗兰克

<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

关于AbsoluteLayout,官方文档有说明:

AbsoluteLayout 有一个独特的锚点模型,当使用比例定位时,元素的锚点相对于其元素定位,就像元素相对于布局定位一样。使用绝对定位时,锚点位于视图内的 (0,0) 处。这有两个重要的后果:

  • 不能使用比例值将元素定位在屏幕之外。
  • 无论布局或设备的大小如何,元素都可以可靠地放置在布局的任何一侧或中心。

AbsoluteLayout,与 RelativeLayout 一样,能够定位元素,使它们重叠。

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.

也许这似乎很难理解,但是AbsoluteLayout就像this.Here是关于Anchor在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>

如果像这样使用 AbsoluteLayout,它将起作用:

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

这里AbsoluteLayout不是实现你想要的最好方案,你可以尝试使用ViewCell中的Grid布局如下:

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

你说得对,AbsolueLayout一开始很难理解,他们快把我逼疯了。但是两个小时后,我通过你的例子理解了它。 docu 的关键是第一句话:值 X 和 Y 更改元素 AND 周围视图中的锚点。在所附的图片中,您(我认为)可以很好地理解这一点。我现在继续使用 AbsoluteLayout,因为它可以让我很好地实现所有计划好的布局。非常感谢您的精神提升。

enter image description here