2016-04-22 12 views
3

OK、私はあきらめます。この単純なことを達成しようとするのに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つの画像(3つのレイヤーが重なっているようなもの)からなる「1つの画像」を作成する必要があります。そのためには、画像のためだけにAbsoluteLayoutが必要です。

このファイルのすべてのビューに対して可能なすべての組み合わせを試しましたが、何も機能しません。

問題は、スクロールが常に画像の下に大きなスペースを残してしまうことです。そして、緑の色では、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日間それに固執している、私は他に何をするか分からない。

ScrollView.ContentにはRelativeLayoutを使ってみました。そしてそれを理解しようと一日のうちに(私が完全に行ったかどうかわからない)、私はもっと悪い問題を抱えていました。 RelativeLayoutは、Scrollの高さをオーバーフローさせ、タブの背後にある画像の一部を隠します(ベースアプリのコンテナ)。

しかし、私は実際にStackLayout->items + AbsoluteLayoutアプローチを維持したいと思います。

何か助けていただきありがとうございます。

+0

代わりにグリッドを使用したことはありますか?あなたが望むものを得るには、(少なくとも私の意見では)やや簡単な方法でしょうか。絶対レイアウトは、その性質上、あなたがそれについて何もできることがなければ、絶対的な最後の手段になるはずです。 – EvilBeer

+0

私は非常にはっきりしていないかもしれません。私はAbsoluteLayoutが必要です。なぜなら、3つの画像がオーバーレイされているからです。彼らは透明性を持つpngです。 – Dpedrinha

答えて

2

問題は、子のサイズ変更イベントを処理していないAbsoluteLayoutにあることがわかりました。適切なイベントをディスパッチしていないImage要素の問題か、それをうまく処理しないAbsoluteLayoutです。 私はこのイベント処理を作成するだけでした。 Image.SizeChangedにリスナーを追加して、AbsoluteLayoutの高さを設定します。私の場合のために動作しますが、あなたはAbsoluteLayoutのために、より複雑な子気質を持っている場合は、そのようなことが必要になります

 private void BackImg_SizeChanged(object sender, EventArgs e) 
     { 
      ImgsContainer.HeightRequest = BackImg.Height; 
     } 

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

これは、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を子供に使用しないでください。

代わりに、アブソリュートレイアウトに関して子供をレイアウトする方法を正確に示す他の方法があります。

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

そしてMidImgとFrontImgについて同じこと:C#の代わりに、XAMLを使用して、あなたのような何かをしたいです。

SetLayoutFlagsは、親に比例して子のサイズおよび/または位置のどの側面をシステムに通知します。次に、それをレイアウトする方法の詳細がSetLayoutBoundsに示されます。この場合、コードはBackImgを左上隅にレイアウトするように言います。

+0

ご清聴ありがとうございます。私はそれを試みたが、問題は続く。子のサイズ変更後にAbsoluteLayoutは縮小されません。 – Dpedrinha