Фон градиента рамки Xamarin.Forms перетекает через его границы на Android - PullRequest
0 голосов
/ 03 марта 2020

Я сделал пользовательский фрейм в Xamarin.Forms, который допускает 3-х цветной линейный градиент и некоторые другие вещи. Тем не менее, я замечаю, что когда я устанавливаю градиент для пользовательского фрейма, который находится внутри сетки, он будет рисовать поверх всего, что над ним. См. Ниже:

enter image description here

Принимая во внимание, что если я просто установлю фон в solid цвет, например, розовый (т.е. не буду использовать функцию градиента), рамка не перетекает См. Ниже:

enter image description here

вот код для пользовательского средства визуализации, которое я использую для 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;
        }
    }

Is возможно, что когда я устанавливаю линейный градиент на 0,0 для x и y, это не относится к 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>

Любая помощь будет высоко оценена, заранее спасибо!

1 Ответ

1 голос
/ 03 марта 2020

В ваших пользовательских фреймах установите IsClippedToBounds="True"

Цитирование Документация :

Получает или задает значение, которое определяет, должен ли макет обрезать его потомки до его границ.

<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)
{

}
...