【问题标题】:Positioning elements within a listview with xaml / xamarin使用 xaml / xamarin 在列表视图中定位元素
【发布时间】:2019-08-30 09:06:21
【问题描述】:

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

【问题讨论】:

    标签: xaml listview xamarin absolutelayout


    【解决方案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>
    

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

    【讨论】:

    • 嘿Jiangjiang,是的,这看起来更像是我想要的。那应该是一个更好的起始位置。布局似乎有时比想象的要难。对我来说,没有任何暗示为什么绝对版本不起作用。但在这一点上非常感谢。弗兰克
    • @Frank 如果想使用AbsoluteLayout,我已经更新了答案。
    • 如果您有更多关于 AbsoluteLayout 的信息,我很感兴趣,因为我想了解它们。不知道什么时候需要。;-)
    • @Frank 很高兴能帮上忙,如果你投赞成票,请不要介意。我更新了一个示例的答案,以展示锚在 AbsoluteLayout 中的工作原理。
    【解决方案2】:

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

    enter image description here

    【讨论】:

    • 这张图真的很有帮助。你能提供更多关于 AbsoluteLayout 锚点的阅读吗?我不认为官方文档解释得很好。
    猜你喜欢
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    • 2016-10-27
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多