使用 xaml / xamarin 在列表视图中定位元素
Positioning elements within a listview with xaml / xamarin
我想了解如何在列表视图 (CustomCell) 中定位元素,因为这将是我的主要显示元素。
但是我在使用AbsoluteLayout标签时遇到了困难,也许任何人都可以提供一些提示。
我正在使用 VisualStudio 2017 15.9,在 Android 模拟器上对其进行测试(但认为这无关紧要)
我有一个来自互联网的例子,什么是 运行,原则上我理解它。我尝试了各种方法来根据需要定位元素,但没有成功。
- 例如,无论图像大小如何,我都希望两个标签始终位于行的中间 (x=50%)。 AbsoluteLayout 没有按预期工作,可能是因为它位于 StackLayout 中。
标签总是紧跟在图像后面,中间有一点间隙。
- 此外,我想将第二个标签定位在 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
我想了解如何在列表视图 (CustomCell) 中定位元素,因为这将是我的主要显示元素。 但是我在使用AbsoluteLayout标签时遇到了困难,也许任何人都可以提供一些提示。
我正在使用 VisualStudio 2017 15.9,在 Android 模拟器上对其进行测试(但认为这无关紧要)
我有一个来自互联网的例子,什么是 运行,原则上我理解它。我尝试了各种方法来根据需要定位元素,但没有成功。
- 例如,无论图像大小如何,我都希望两个标签始终位于行的中间 (x=50%)。 AbsoluteLayout 没有按预期工作,可能是因为它位于 StackLayout 中。
标签总是紧跟在图像后面,中间有一点间隙。
- 此外,我想将第二个标签定位在 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