这是我的场景(并非所有在同一个XAML文件中):
<TabbedPage>
<NavigationPage>
<ContentPage/>
<ContentPage/>
<CarouselPage>
<CarouselContentPage>
这是CarouselContentPage
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.Layouts.PointInfoDataTemplate"
>
<ContentPage.Content>
<ScrollView Orientation="Vertical" BackgroundColor="Navy" VerticalOptions="Fill">
<StackLayout x:Name="MyStackLayout" HorizontalOptions="StartAndExpand" VerticalOptions="Start" BackgroundColor="Gray">
<Label x:Name="NameLabel" FontSize="Medium" HorizontalOptions="Center"/>
<Label x:Name="DescLabel" FontSize="Medium" HorizontalOptions="Center" />
<AbsoluteLayout x:Name="ImgsContainer" VerticalOptions="Start" BackgroundColor="Green">
<Image x:Name="BackImg" Aspect="AspectFit" VerticalOptions="Start"/>
<Image x:Name="MidImg" Aspect="AspectFit" VerticalOptions="Start"/>
<Image x:Name="FrontImg" Aspect="AspectFit" VerticalOptions="Start"/>
</AbsoluteLayout>
</StackLayout>
</ScrollView>
</ContentPage.Content>
</ContentPage>
我需要的是简单的,垂直滚动页面上有一些垂直堆叠的标签,之后我需要创建“一个图像”,它由3个图像组成,彼此重叠(如3层重叠)。为此,我需要AbsoluteLayout
仅用于图像,对吗?
我已经为此文件中的所有视图尝试了VerticalOptions
的所有可能组合,但没有任何效果。
问题是滚动总是在图像下面留下很大的空间。并且使用绿色,这意味着AbsoluteLayout
在图像调整大小后不会缩小其高度。图像可以具有可变的大小和形状(尽管每个页面内的3个都具有相同的尺寸)并且它们都比任何智能手机屏幕都大(稍后的缩放功能)。所以我需要图像使用所有可用的宽度并保持纵横比(我相信AspectFit
)。
所有图片均为嵌入式资源。以下是CarouselContentPage
背后的代码:
public PointInfoDataTemplate(PointModel point)
{
InitializeComponent();
NameLabel.Text = point.nome;
DescLabel.Text = point.apelido;
BackImg.Source = ImageSource.FromResource(point.backimg);
MidImg.Source = ImageSource.FromResource(point.midimg);
FrontImg.Source = ImageSource.FromResource(point.frontimg);
//BackImg.SizeChanged += delegate {
// ImgsContainer.Layout(new Rectangle(imgsContainer.Bounds.X, imgsContainer.Bounds.Y, BackImg.Bounds.Width, BackImg.Bounds.Height));
// MyStackLayout.Layout(new Rectangle(imgsContainer.Bounds.X, imgsContainer.Bounds.Y, BackImg.Bounds.Width, BackImg.Bounds.Height));
//};
}
我甚至在SizeChanged
事件后尝试调整了Layouts的大小,但它也没有用。
所以也许我做错了,这是我的所有代码。我被困了3天,我不知道还能做什么。
我尝试使用RelativeLayout
作为ScrollView.Content
。经过一整天试图理解它(并且不确定我是否完全做到了),我遇到了更糟糕的问题。 RelativeLayout
会溢出Scroll
高度并隐藏标签后面的部分图片(基本应用容器)。
但我真的想保留StackLayout->items + AbsoluteLayout
方法。
我感谢任何帮助。
答案 0 :(得分:2)
我发现问题出在AbsoluteLayout
未处理其子调整大小事件上。要么Image元素没有调度正确的事件,要么AbsoluteLayout
没有很好地处理它们。
所以我需要的只是创建这个事件处理。
添加了Image.SizeChanged
的监听器以设置AbsoluteLayout
高度。
private void BackImg_SizeChanged(object sender, EventArgs e)
{
ImgsContainer.HeightRequest = BackImg.Height;
}
这适用于我的情况,但是如果你对AbsoluteLayout
有更复杂的子处理,你将需要这样的东西:
private void ChildAdded_EventHandler(object sender, EventArgs e) {
double neededHeight = 0;
foreach(var child in sender) {
if(neededHeight < child.Y+child.Height) {
neededHeight = child.Y+child.Height;
}
}
sender.HeightRequest = neededHeight;
}
您必须将此事件处理程序添加到AbsoluteLayout.ChildAdded
和AbsoluteLayout.ChildRemoved
;
答案 1 :(得分:1)
它在C#中不是XAML,但它应该很容易转换
Grid imageContainer = new Grid() {
HeightRequest = 400,
Children = {
new Image(), //Image 1
new Image(), //Image 2 on top of image 1
new Image(), //Image 3 on top of image 2 and 1
}
}
Content = new ScrollView() {
Content = new Grid() {
RowDefinitions = {
new RowDefinition(){Height = new GridLength(1, GridUnitType.Auto)}, //label1
new RowDefinition(){Height = new GridLength(1, GridUnitType.Auto)}, //label2
new RowDefinition(){Height = new GridLength(1, GridUnitType.Auto)}, //image container
},
Children ={
{new Label(), 0, 0}, //Label 1
{new Label(), 0, 1}, //Label 2
{imageContainer, 0, 2} //image container
}
}
};
答案 2 :(得分:1)
如果网格解决方案有效,那可能会更容易,但因为您询问了AbsoluteLayout ......
要使AbsoluteLayout正常工作,您不要在子项上使用与其他视图相同的VerticalOptions。
相反,还有其他方法可以准确指出如何布置与绝对布局相关的孩子。使用C#代替Xaml,您可以执行以下操作:
AbsoluteLayout.SetLayoutFlags(BackImg,
AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(BackImg,
new Rectangle(0, 0, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
对于MidImg和FrontImg也是如此。
SetLayoutFlags告诉系统子项的大小和/或位置的哪些方面与父项成比例。然后SetLayoutBounds提供了如何布局的详细信息。在这种情况下,代码说要在左上角布置BackImg。