Xamarin.Forms: 如何在 2 个 ScrollLayout 之上和之间放置一个 Circle Image

Xamarin.Forms: how to position a Circle Image above and between 2 ScrollLayout

我在 Xamarin.Forms 应用程序 上工作,其中包含 主页 基于:

如果列表包含很多信息,ScrollView可以恢复Image

看起来像这样:

XAML 看起来像这样:

<Grid RowSpacing="0"
        BackgroundColor="{StaticResource Gray-050}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid Grid.Row="1">
        <!--  Header view  -->
        <ScrollView>
            <ContentView x:Name="headerView"
                         HorizontalOptions="FillAndExpand"
                         VerticalOptions="FillAndExpand">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <!-- the BoxView will be replaced by an Image -->
                    <BoxView x:Name="headerImage"
                                HeightRequest="280"
                                BackgroundColor="Yellow" />
                </Grid>
            </ContentView>
        </ScrollView>

        <!--  List view  -->
        <ScrollView HorizontalOptions="FillAndExpand"
                    VerticalOptions="FillAndExpand">
            <Grid ColumnSpacing="0"
                  RowSpacing="0"
                  VerticalOptions="FillAndExpand">
                <Grid.RowDefinitions>
                    <RowDefinition Height="140" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Grid Grid.Row="1">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <!-- Main container -->
                    <yummy:PancakeView CornerRadius="16,16,0,0"
                                       Padding="0,10,0,0"
                                       BackgroundColor="{StaticResource Gray-050}"
                                       Grid.Row="1">
                        <StackLayout BackgroundColor="Transparent"
                                     Spacing="16" Margin="16">

                            <!-- Phone container -->
                            <yummy:PancakeView Style="{StaticResource YummyHomeFrame}"
                                                Padding="16">
                                <Grid RowSpacing="0">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*" />
                                        <RowDefinition Height="*" />
                                    </Grid.RowDefinitions>
                                    <Label Style="{StaticResource HomePageHeaderLabelStyle}"
                                            Text="Phone Number" />
                                    <Label Grid.Row="1"
                                            Style="{StaticResource HomePageLabelStyle}"
                                            Text="+33 6 20 10 70 40"  />
                                </Grid>
                            </yummy:PancakeView>

                            <!-- Other containers -->

                        </StackLayout>
                    </yummy:PancakeView>
                </Grid>
            </Grid>
        </ScrollView>
    </Grid>
</Grid>

我想在 2 个 ScrollViews 之间显示 圆形徽标 ,就在 MainContainer 上方,如下所示:

但是我没有做到,不知道有没有可能...

您可以尝试使用 RelativeLayout 来实现。

下面是类似的示例代码:

<ScrollView HorizontalOptions="FillAndExpand"
                VerticalOptions="FillAndExpand">
        <Grid ColumnSpacing="0"
                RowSpacing="0"
                VerticalOptions="FillAndExpand">
            <Grid.RowDefinitions>
                <RowDefinition Height="140" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid Grid.Row="1">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <!-- Main container -->
                <RelativeLayout>
                    <Frame CornerRadius="16" x:Name="MainFrame"
                                    Padding="0,10,0,0"
                                    BackgroundColor="LightBlue"
                                    Grid.Row="1">
                    <StackLayout BackgroundColor="Transparent"
                                    Spacing="16"
                                    Margin="16">

                        <!-- Phone container -->
                        <Frame Padding="16">
                            <Grid RowSpacing="0">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*" />
                                    <RowDefinition Height="*" />
                                </Grid.RowDefinitions>
                                <Label Text="Phone Number" />
                                <Label Grid.Row="1"
                                        Text="+33 6 20 10 70 40" />
                            </Grid>
                        </Frame>

                        <!-- Other containers -->

                    </StackLayout>
                </Frame>
                    <BoxView CornerRadius="25"
                                BackgroundColor="AliceBlue"
                                RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=MainFrame, Property=Width,Factor=0.45}"
                                RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=MainFrame, Property=Y,Constant=-20}"
                                RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=MainFrame,  Constant=100}"
                                RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToView, ElementName=MainFrame, Constant=100}" />
                </RelativeLayout>
            </Grid>
        </Grid>
</ScrollView>

效果:

在容器的同一层添加你的圆圈标志。

                <!--  Items view  -->
                <ScrollView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                    <Grid
                        ColumnSpacing="0"
                        RowSpacing="0"
                        VerticalOptions="FillAndExpand">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="140" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <Grid Grid.Row="1">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>

                            <!--  Container  -->
                            <Frame ...>

                            <!--  Yoour logo -->
                            <Frame
                                Grid.Row="1"
                                Margin="0,-40,0,0"
                                BackgroundColor="Green"
                                CornerRadius="40"
                                HeightRequest="40"
                                HorizontalOptions="Center"
                                VerticalOptions="Start"
                                WidthRequest="40" />
                        </Grid>
                    </Grid>
                </ScrollView>

查看演示:

因为我没有使用 nugget 包,所以我只是用框架替换了 pancake 视图。并且您可以根据需要调整徽标大小和边距。

顺便说一句,你的结构有点复杂或冗余,可以是一个4级的主结构如下:

<Grid x:Name="mainGrid">

  <!--  Header view  -->
  <BoxView (or Image).../>

  <!--  Items view  -->
  <ScrollView ...>
    <Grid ...>

      <!--  Container  -->
      <Frame ...>

      <!--  logo  -->
      <Frame (or Image)...>

    </Grid>
  </ScrollView>
</Grid>

谢谢@Shaw 和@Junior Jiang - MSFT

2 种解决方案没有 RelativeLayout

版本没有 RelativeLayout 由@Shaw 提供。

<Grid RowSpacing="0"
        BackgroundColor="LightGray"
        x:Name="mainGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid Grid.Row="1">
        <!--  Header view  -->
        <ScrollView>
            <ContentView x:Name="headerView"
                            HorizontalOptions="FillAndExpand"
                            VerticalOptions="FillAndExpand">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <!-- the BoxView can be replaced by an Image -->
                    <BoxView x:Name="headerImage"
                                HeightRequest="280"
                                BackgroundColor="Yellow" />
                </Grid>
            </ContentView>
        </ScrollView>
            <!-- Content View -->
        <ScrollView HorizontalOptions="FillAndExpand"
                    VerticalOptions="FillAndExpand">
            <Grid ColumnSpacing="0"
                    RowSpacing="0"
                    VerticalOptions="FillAndExpand">
                <Grid.RowDefinitions>
                    <RowDefinition Height="140" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Grid Grid.Row="1">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <!-- Frame Container-->
                    <Frame x:Name="MainFrame"
                            CornerRadius="16"
                            Padding="0,10,0,0"
                            BackgroundColor="LightGray"
                            Grid.Row="1">
                        <StackLayout BackgroundColor="Transparent"
                                        Spacing="16" Margin="16,48,16,16">
                            <!-- Phone Frame -->
                            <Frame Padding="16">
                                <Grid RowSpacing="0">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*" />
                                        <RowDefinition Height="*" />
                                    </Grid.RowDefinitions>
                                    <Label Text="Phone Number" />
                                    <Label Grid.Row="1"
                                            Text="+33 6 20 10 70 40"  />
                                </Grid>
                            </Frame>
                            <!-- Other Frames -->
                            <!-- ... -->
                        </StackLayout>
                    </Frame>
                    <!-- No RelativeLayout positioned item -->
                    <BoxView Grid.Row="1"
                                CornerRadius="45"
                                BackgroundColor="DarkBlue"
                                WidthRequest="90" HeightRequest="90"
                                VerticalOptions="Start" HorizontalOptions="Center"
                                Margin="0,-45,0,0" />
                </Grid>
            </Grid>
        </ScrollView>
    </Grid>
</Grid>

版本 RelativeLayout基于@Junior Jiang - MSFT 建议:

<Grid RowSpacing="0"
        BackgroundColor="LightGray"
        x:Name="mainGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid Grid.Row="1">
        <!--  Header View  -->
        <ScrollView>
            <ContentView x:Name="headerView"
                            HorizontalOptions="FillAndExpand"
                            VerticalOptions="FillAndExpand">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <!-- the BoxView can be replaced by an Image -->
                    <BoxView x:Name="headerImage"
                                HeightRequest="280"
                                BackgroundColor="Yellow" />
                </Grid>
            </ContentView>
        </ScrollView>
        <!-- Content View -->
        <ScrollView HorizontalOptions="FillAndExpand"
                    VerticalOptions="FillAndExpand">
            <Grid ColumnSpacing="0"
                    RowSpacing="0"
                    VerticalOptions="FillAndExpand">
                <Grid.RowDefinitions>
                    <RowDefinition Height="140" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <StackLayout Grid.Row="1">
                    <RelativeLayout>
                        <!-- Frame container -->
                        <Frame x:Name="MainFrame"
                                CornerRadius="16"
                                Padding="0,10,0,0"
                                BackgroundColor="LightGray"
                                        Grid.Row="1">
                            <StackLayout BackgroundColor="Transparent"
                                        Spacing="16" Margin="16,48,16,16">
                                <!-- Phone Frame -->
                                <Frame Padding="16">
                                    <Grid RowSpacing="0">
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="*" />
                                            <RowDefinition Height="*" />
                                        </Grid.RowDefinitions>
                                        <Label Text="Phone Number" />
                                        <Label Grid.Row="1"
                                            Text="+33 6 20 10 70 40"  />
                                    </Grid>
                                </Frame>
                                <!-- Other Frames -->
                                <!-- ... -->
                            </StackLayout>
                        </Frame>
                        <!-- RelativeLayout positioned item -->
                        <BoxView CornerRadius="45"
                                BackgroundColor="DarkBlue"
                                WidthRequest="90" HeightRequest="90"
                                VerticalOptions="Center" HorizontalOptions="Center"
                                RelativeLayout.XConstraint="{ConstraintExpression 
                                                                Type=RelativeToParent,
                                                                Property=Width, 
                                                                Factor=0.5,
                                                                Constant=-45}"
                                RelativeLayout.YConstraint="{ConstraintExpression
                                                                Type=RelativeToView,
                                                                ElementName=MainFrame,
                                                                Property=Y,Constant=-45}" />
                    </RelativeLayout>
                </StackLayout>
            </Grid>
        </ScrollView>
    </Grid>
</Grid>