【问题标题】:Xamarin.Forms Frame Gradient Background spills over its boundaries on AndroidXamarin.Forms 框架渐变背景在 Android 上溢出其边界
【发布时间】:2020-03-04 07:47:30
【问题描述】:

我在 Xamarin.Forms 中制作了一个自定义框架,它允许 3 色线性渐变和其他一些东西。但是,我注意到,当我在 Grid 内部的自定义框架上设置渐变时,它将覆盖其上方的所有内容。见下文:

然而,如果我只是将背景设置为像粉红色这样的纯色(即不使用渐变功能),则框架不会溢出。见下文:

这是我用于 Android 的自定义渲染器的代码:

 protected override void DispatchDraw(Canvas canvas)
    {
        var gradient = new Android.Graphics.LinearGradient(
            0, 0, Width, Height,
            new int[] { _startColor.ToAndroid(), _middleColor.ToAndroid(), _endColor.ToAndroid() },
            null,
            Android.Graphics.Shader.TileMode.Mirror);
        var paint = new Android.Graphics.Paint()
        {
            Dither = true,
        };
        paint.SetShader(gradient);
        canvas.DrawPaint(paint);
        base.DispatchDraw(canvas);
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
    {
        base.OnElementChanged(e);
        if(e.NewElement != null && Control != null && e.NewElement is CustomFrame frame)
        {
            _startColor = frame.StartColor;
            _middleColor = frame.MiddleColor;
            _endColor = frame.EndColor;
        }
    }

是否有可能我将 x 和 y 的线性渐变设置为 0,0 不是指控件的 x 和 y,而是指整个屏幕的 x 和 y?

如果您需要,以下是 xaml 的粗略示例:

    <Grid RowSpacing="0"
              ColumnSpacing="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="25*"/>
                <RowDefinition Height="10*"/>
                <RowDefinition Height="40*"/>
                <RowDefinition Height="10*"/>
                <RowDefinition Height="40*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Grid x:Name="header"
                  HorizontalOptions="Center"
                  VerticalOptions="CenterAndExpand"
                  Grid.Row="0"
                  Grid.ColumnSpan="4"
                  RowSpacing="0"
                  BackgroundColor="White">
                <CarouselView ItemsSource=""
                              CurrentItem=""
                              VerticalOptions="CenterAndExpand"
                              HorizontalOptions="Center"
                              PeekAreaInsets="30"
                              x:Name="dayCarousel">
                    <CarouselView.ItemsLayout>
                        <LinearItemsLayout Orientation="Horizontal"
                                           SnapPointsAlignment="Center"
                                           SnapPointsType="MandatorySingle"/>
                    </CarouselView.ItemsLayout>
                    <CarouselView.ItemTemplate>
                        <DataTemplate>
                            <ContentView>
                                <StackLayout VerticalOptions="CenterAndExpand"
                                             HorizontalOptions="Center"
                                             BackgroundColor="White">
                                    <StackLayout.Triggers>
                                        <DataTrigger TargetType="StackLayout"
                                                         Binding="{Binding IsSelected}"
                                                         Value="False">
                                            <Setter Property="Scale"
                                                        Value="0.85"/>
                                            <Setter Property="Opacity"
                                                        Value="0.60"/>
                                        </DataTrigger>
                                    </StackLayout.Triggers>
                                </StackLayout>
                            </ContentView>
                        </DataTemplate>
                    </CarouselView.ItemTemplate>
                </CarouselView>
            </Grid>
            <cntrl:CustomFrame CornerRadius="20,20,0,0"
                               Grid.Row="1"
                               Grid.Column="2"
                               StartColor="{StaticResource GracePink}"
                               MiddleColor="{StaticResource GracePurple}"
                               EndColor="{StaticResource GraceDarkPurple}">
            </cntrl:CustomFrame>

            <cntrl:CustomFrame CornerRadius="40,40,0,0"
                               Grid.Row="2"
                               Grid.RowSpan="3"
                               Grid.ColumnSpan="4"
                               StartColor="{StaticResource GracePink}"
                               MiddleColor="{StaticResource GracePurple}"
                               EndColor="{StaticResource GraceDarkPurple}">
            </cntrl:CustomFrame>


            <cntrl:CustomFrame BackgroundColor="White"
                               CornerRadius="20,20,0,0"
                               Grid.Row="3"
                               Grid.Column="1">
            </cntrl:CustomFrame>
            <cntrl:CustomFrame BackgroundColor="White"
                               Grid.Row="4"
                               CornerRadius="40,40,0,0"
                               Grid.ColumnSpan="4">
            </cntrl:CustomFrame>
</Grid>

任何帮助将不胜感激,在此先感谢您!

【问题讨论】:

    标签: xamarin.forms gradient frame


    【解决方案1】:

    在您的自定义框架中,设置IsClippedToBounds="True"

    引用Documentation

    获取或设置一个值,该值确定布局是否应将其子级剪辑到其边界。

    <cntrl:CustomFrame CornerRadius="20,20,0,0"
                       Grid.Row="1"
                       Grid.Column="2"
                       IsClippedToBounds="True"
                       StartColor="{StaticResource GracePink}"
                       MiddleColor="{StaticResource GracePurple}"
                       EndColor="{StaticResource GraceDarkPurple}">
    </cntrl:CustomFrame>
    

    如果 IsClipToBounds 不起作用,请尝试在 OnElementChanged 中执行此操作

    try
    {
        if (e.NewElement != null && Control != null && e.NewElement is CustomFrame frame)
        {
            _startColor = frame.StartColor;
            _middleColor = frame.MiddleColor;
            _endColor = frame.EndColor;
    
            var orientation = GradientDrawable.Orientation.ToBottomRight;
            var gradient = new GradientDrawable(orientation, new[] { _startColor .ToAndroid().ToArgb(), _middleColor.ToAndroid().ToArgb(), _endColor .ToAndroid().ToArgb() });
            ViewCompat.SetBackground(this, gradient);
        }
    }
    catch (Exception ex)
    {
    
    }
    

    【讨论】:

    • 那么看来您执行 CustomRender 的方式正在影响框架检测其子边界的能力.. 另外,我只记得这种渐变布局有一个很棒的插件,看看这个:medium.com/@benetskyybogdan/…
    • @JonathanCook 我对我的 anwser 进行了编辑,尝试在您的 OnElementChanged 中进行此验证,看看它是否解决了您的问题,如果没有,我没有想法
    • 成功了!谢谢你!现在我需要弄清楚如何让两个帧上的渐变匹配哈哈,但这是一个不同的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 2022-12-14
    • 2012-01-31
    • 1970-01-01
    • 2013-07-17
    相关资源
    最近更新 更多