2016-04-22 47 views
3

好吧,我放棄了。花了3天時間來完成這個簡單的事情。如何正確使用Xamarin中ScrollView內的StackLayout中的AbsoluteLayout?

這裏是我的情況下(不是全部在同一個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事件之後調整的佈局,但它也不能工作。

所以也許我做錯了什麼,這是我所有的代碼。我堅持了3天,我不知道還有什麼要做。

我試圖用一個RelativeLayoutScrollView.Content。經過整整一天的努力去理解它(不知道我是否完全做到了),我遇到了更糟的問題。 RelativeLayout將溢出Scroll高度並隱藏選項卡(基本應用程序容器)後面的部分圖像。

但我真的很想保留StackLayout->items + AbsoluteLayout方法。

我很感激任何幫助。

+0

您是否考慮過使用網格?將是一個相當容易(至少在我看來)的方式來得到你想要的。由於它的性質,如果沒有別的可以做的事情,絕對佈局應該是絕對的最後手段。 – EvilBeer

+0

我可能不是很清楚。我需要AbsoluteLayout,因爲覆蓋了3張圖片。他們是透明的PNG。 – Dpedrinha

回答

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.ChildAddedAbsoluteLayout.ChildRemoved;

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 
        } 
    } 
}; 
+0

我會嘗試。我不知道一個單元格的行爲是絕對佈局。 – Dpedrinha

+0

我覺得網格是在90%的時間內設計你的應用程序的最簡單方法。如果遇到問題,我可以在明天轉換xaml中的代碼。只需在這裏回答。 – FriedSloth

+0

謝謝,但我找到了解決方法。看看我的答案。 – Dpedrinha

1

如果電網解決方案的工作,這可能是更容易,但既然你問AbsoluteLayout ...

要獲得AbsoluteLayout爲了工作,您不會在孩子身上使用相同的VerticalOptions,而您會爲其他視圖使用相同的VerticalOptions。

相反,還有其他的方法來準確指定如何佈局的孩子對於絕對佈局。使用C#,而不是XAML中,你會做這樣的事情:

AbsoluteLayout.SetLayoutFlags(BackImg, 
    AbsoluteLayoutFlags.PositionProportional); 
AbsoluteLayout.SetLayoutBounds(BackImg, 
    new Rectangle(0, 0, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize)); 

而對於MidImg和FrontImg同樣的事情。

SetLayoutFlags告訴系統孩子的大小和/或位置與父母成比例的哪些方面。然後SetLayoutBounds給出瞭如何佈置它的細節。在這種情況下,代碼說在左上角佈置BackImg。

+0

感謝您澄清。我嘗試過,但問題仍然存在。子調整大小後,AbsoluteLayout不會縮小。 – Dpedrinha

相關問題