Как установить CornerRadius в рамку с элементами внутри (Xamarin.Формы)
Мне нужно скруглить углы рамки, но мой код не работает. Я думаю, что проблема в том, что у меня есть два 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 ответов:
Вы можете создать пользовательский визуализатор для углового радиуса на рамке. Прежде всего, создайте пользовательский элемент управления, который наследуется от фрейма в вашем переносимом проекте как:
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; } }
С помощью кода шоу я нашел решение!
Я удалил рамку и заменил два stacklayout внутри сетки двумя различными 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 (я его еще не тестировал) после:
Layer.CornerRadius = cornerRadius;Поставить:
//in LeftCornerRadiusFrameRenderer Layer.MaskedCorners = (CoreAnimation.CACornerMask)5; //in RightCornerRadiusFrameRenderer Layer.MaskedCorners = (CoreAnimation.CACornerMask)10;
Comments