Как установить CornerRadius на рамку с элементами внутри (Xamarin.Forms) - PullRequest
0 голосов
/ 14 мая 2018

Мне нужно установить углы рамки закругленными, но мой код не работает. Я думаю, что проблема в том, что у меня есть два StackLayout с BackgroundColor. Почему с IsClippedToBounds = "True" не работает?

Так и должно быть

Это то, что я получаю

и это код:

    <Frame  CornerRadius="20"
            Margin="15,7,15,7"
            Padding="0"
            IsClippedToBounds="True">
        <Grid   
            IsClippedToBounds="True"
            ColumnSpacing="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="50" />
            </Grid.ColumnDefinitions>
            <StackLayout    Grid.Row="0"
                            Grid.Column="0"
                            BackgroundColor="{DynamicResource DarkGray}"
                            Padding="10">

                <Label>...<Label>
            </StackLayout>

            <StackLayout    Grid.Row="0"
                            Grid.Column="1"
                            BackgroundColor="{DynamicResource DarkGrayVariant}"
                            Padding="10">

                <Image>...</Image>
            </StackLayout>

        </Grid>
    </Frame>

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

С помощью кода Shaw я нашел решение!

Я удалил фрейм и заменил два стека в сетке на два разных CustomRenderer, один для закругления левых углов и один для правых углов.

<Grid   ColumnSpacing="0"
        Padding="15,7,15,7">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="50" />
        </Grid.ColumnDefinitions>
        <customRenders:LeftCornerRadiusFrame  CornerRadius="5"
                                                    Grid.Row="0"
                                                    Grid.Column="0"
                                                    Padding="10"
                                                    BackgroundColor="{DynamicResource DarkGray}">

            <Label>...</Label>

        </customRenders:LeftCornerRadiusFrame>

        <customRenders:RightCornerRadiusFrame Grid.Row="0"
                                                    Grid.Column="1"
                                                    CornerRadius="5"
                                                    Padding="10"
                                                    BackgroundColor="{DynamicResource DarkGrayVariant}">

            <Image>...</Image>

        </customRenders:RightCornerRadiusFrame>

    </Grid>

В устройстве визуализации Android удалите конструктор и замените:

gi.SetCornerRadius(origFrame.CornerRadius);

на:

//in LeftCornerRadiusFrameRenderer
gi.SetCornerRadii(new float[] { origFrame.CornerRadius, origFrame.CornerRadius, 0, 0, 0, 0, origFrame.CornerRadius, origFrame.CornerRadius });

//in RightCornerRadiusFrameRenderer
gi.SetCornerRadii(new float[] { 0, 0, origFrame.CornerRadius, origFrame.CornerRadius, origFrame.CornerRadius, origFrame.CornerRadius, 0, 0 });

В приложении IOS Renderer (я еще не проверял его)) после:

Layer.CornerRadius = cornerRadius;

поставить:

//in LeftCornerRadiusFrameRenderer
Layer.MaskedCorners = (CoreAnimation.CACornerMask)5;

//in RightCornerRadiusFrameRenderer
Layer.MaskedCorners = (CoreAnimation.CACornerMask)10;
0 голосов
/ 14 мая 2018

Вы можете создать собственный рендерер для углового радиуса на рамке. Прежде всего, создайте пользовательский элемент управления, который наследуется от фрейма в вашем переносимом проекте как:

public class ExtendedFrame : Frame
{
    public new Thickness Padding { get; set; } = 0;
    public int BorderThickness { get; set; } 
    public ExtendedFrame()
    {
        base.Padding = this.Padding;
    }
}

Затем вы можете реализовать рендер, как показано ниже:

Для Android:

public class ExtendedFrameRenderer : FrameRenderer
{
    GradientDrawable _gi;

    public ExtendedFrameRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
    {
        base.OnElementChanged(e);

        var origFrame = e.NewElement as ExtendedFrame;

        if(origFrame != null)
        {
            GradientDrawable gi = new GradientDrawable();

            _gi = gi;

            gi.SetStroke(origFrame.BorderThickness, origFrame.OutlineColor.ToAndroid());
            gi.SetColor(origFrame.BackgroundColor.ToAndroid());
            gi.SetCornerRadius(origFrame.CornerRadius);
#pragma warning disable CS0618 // Type or member is obsolete
            SetBackgroundDrawable(gi);
#pragma warning restore CS0618 // Type or member is obsolete
        }
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (ChildCount > 0 && _gi != null)
        {
#pragma warning disable CS0618 // Type or member is obsolete
            SetBackgroundDrawable(_gi);
#pragma warning restore CS0618 // Type or member is obsolete
        }

        base.OnElementPropertyChanged(sender, e);
    }
}

Для IOS:

 public class ExtendedFrameRenderer : FrameRenderer
{


    private ExtendedFrame customFrame;

    protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
    {
        base.OnElementChanged(e);

        if (e.NewElement != null)
        {
            customFrame = e.NewElement as ExtendedFrame;
            SetupLayer();

        }
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName ||
            e.PropertyName == Xamarin.Forms.Frame.OutlineColorProperty.PropertyName ||
            e.PropertyName == Xamarin.Forms.Frame.HasShadowProperty.PropertyName ||
            e.PropertyName == Xamarin.Forms.Frame.CornerRadiusProperty.PropertyName)
        {
            SetupLayer();
        }
    }

    void SetupLayer()
    {
        float cornerRadius = customFrame.CornerRadius;

        if (cornerRadius == -1f)
            cornerRadius = 5f; // default corner radius

        Layer.CornerRadius = cornerRadius;
        Layer.BackgroundColor = customFrame.BackgroundColor.ToCGColor();

        if (customFrame.HasShadow)
        {
            Layer.ShadowRadius = 2;
            Layer.ShadowColor = UIColor.Black.CGColor;
            Layer.ShadowOpacity = 0.3f;
            Layer.ShadowOffset = new SizeF();
        }
        else
            Layer.ShadowOpacity = 0;

        //if (customFrame.OutlineColor == Color.Default)
        //    Layer.BorderColor = UIColor.Clear.CGColor;
        //else
        //{
            Layer.BorderColor = customFrame.OutlineColor.ToCGColor();
            Layer.BorderWidth = customFrame.BorderThickness;
       // }

        Layer.RasterizationScale = UIScreen.MainScreen.Scale;
        Layer.ShouldRasterize = true;
    }
}
...