使用xaml / xamarin

时间:2019-04-09 06:41:56

标签: xaml listview xamarin absolutelayout

我想了解如何在列表视图(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

2 个答案:

答案 0 :(得分:1)

关于AbsoluteLayout,官方文件有一个解释:

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

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

AbsoluteLayoutRelativeLayout一样,能够定位元素,使其重叠。

  

请注意,在共享链接中,该框的锚点是一个白点。注意锚点和盒子在布局中移动时的关系。

也许这似乎很难理解,但是AbsoluteLayout就像这样。下面是有关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>

enter image description here

如果像这样使用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>

enter image description here

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>

enter image description here

答案 1 :(得分:0)

您是对的,一开始很难理解AbsolueLayout,它们几乎使我发疯。但是两个小时后,我通过您的示例理解了这一点。文档的关键是第一句话:X和Y值更改元素 AND 周围视图内的锚点。在所附图片中,您可以(我认为)很好地理解这一点。我现在继续使用AbsoluteLayout,因为它使我能够很好地实现所有计划的布局。非常感谢您的精神投入。

enter image description here