Xamarin 框架只有一个圆角
Xamarin Frame only have a single rounded corner
简单的问题。我需要一个只有一个圆角的框架,而不是所有四个。我怎样才能只圆框的一个角(在我的例子中是右上角)?
另一种表述方式:如何只设置框架的一个角的角半径?
最简单的方法是使用 Nuget PancakeView。
可以在每个顶点指定CornerRadius,达到想要的效果:
示例:
<yummy:PancakeView BackgroundColor="Orange"CornerRadius="60,0,0,60"/>
您可以在 official page.
中阅读更多内容
为帧使用自定义渲染的另一种方式。
1.Create class name CustomFrame, 继承Frame class, 添加BindableProperty CornerRadiusProperty in PCL.
public class CustomFrame: Frame
{
public static new readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(nameof(CustomFrame), typeof(CornerRadius), typeof(CustomFrame));
public CustomFrame()
{
// MK Clearing default values (e.g. on iOS it's 5)
base.CornerRadius = 0;
}
public new CornerRadius CornerRadius
{
get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
}
在 Android 中创建 CustomFrameRender。
using FrameRenderer = Xamarin.Forms.Platform.Android.AppCompat.FrameRenderer;
[assembly: ExportRenderer(typeof(CustomFrame), typeof(CustomFrameRenderer))]
namespace Demo1.Droid
{
class CustomFrameRenderer : FrameRenderer
{
public CustomFrameRenderer(Context context)
: base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
if (e.NewElement != null && Control != null)
{
UpdateCornerRadius();
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == nameof(CustomFrame.CornerRadius) ||
e.PropertyName == nameof(CustomFrame))
{
UpdateCornerRadius();
}
}
private void UpdateCornerRadius()
{
if (Control.Background is GradientDrawable backgroundGradient)
{
var cornerRadius = (Element as CustomFrame)?.CornerRadius;
if (!cornerRadius.HasValue)
{
return;
}
var topLeftCorner = Context.ToPixels(cornerRadius.Value.TopLeft);
var topRightCorner = Context.ToPixels(cornerRadius.Value.TopRight);
var bottomLeftCorner = Context.ToPixels(cornerRadius.Value.BottomLeft);
var bottomRightCorner = Context.ToPixels(cornerRadius.Value.BottomRight);
var cornerRadii = new[]
{
topLeftCorner,
topLeftCorner,
topRightCorner,
topRightCorner,
bottomRightCorner,
bottomRightCorner,
bottomLeftCorner,
bottomLeftCorner,
};
backgroundGradient.SetCornerRadii(cornerRadii);
}
}
}
}
3.using 表单中的自定义框架。
<StackLayout>
<controls:CustomFrame
BackgroundColor="Red"
CornerRadius="0,30,0,0"
HeightRequest="100"
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="100" />
</StackLayout>
更详细的内容请参考:
这是针对 UWP 渲染器的
我使用了 Cherry Bu - MSFT 的解决方案并将其更改为 UWP。在我的项目中,我在 Android、iOS 和 UWP 中使用它并且工作正常。
using System.ComponentModel;
using Windows.UI.Xaml.Media;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
[assembly: ExportRenderer(typeof(CustomFrame), typeof(yourNamespace.UWP.CustomFrameRenderer))]
namespace yourNamespace.UWP
{
public class CustomFrameRenderer : FrameRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
if (e.NewElement != null && Control != null)
{
UpdateCornerRadius();
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == nameof(CustomFrame.CornerRadius) ||
e.PropertyName == nameof(CustomFrame))
{
UpdateCornerRadius();
}
}
private void UpdateCornerRadius()
{
var radius = ((CustomFrame)this.Element).CornerRadius;
Control.CornerRadius = new Windows.UI.Xaml.CornerRadius(radius.TopLeft, radius.TopRight, radius.BottomRight, radius.BottomLeft);
}
}
}
使用 nuget 包 Xamarin.Forms.PancakeView。
查看类似问题的答案:
我使用的简单解决方案是在圆形框架后面设置另一个框架,如下所示
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.05*"/>
<RowDefinition Height="0.05*"/>
<RowDefinition Height="0.8*"/>
<RowDefinition Height="0.05*"/>
<RowDefinition Height="0.05*"/>
</Grid.RowDefinitions>
<Frame
Grid.Row="4"
Padding="0"
BackgroundColor="Green"
CornerRadius="0"/>
<Frame
Grid.Row="3"
Grid.RowSpan="2"
Padding="0"
BackgroundColor="Green"
HasShadow="True"
CornerRadius="20">
</Frame>
</Grid>
简单的问题。我需要一个只有一个圆角的框架,而不是所有四个。我怎样才能只圆框的一个角(在我的例子中是右上角)?
另一种表述方式:如何只设置框架的一个角的角半径?
最简单的方法是使用 Nuget PancakeView。
可以在每个顶点指定CornerRadius,达到想要的效果:
示例:
<yummy:PancakeView BackgroundColor="Orange"CornerRadius="60,0,0,60"/>
您可以在 official page.
中阅读更多内容为帧使用自定义渲染的另一种方式。
1.Create class name CustomFrame, 继承Frame class, 添加BindableProperty CornerRadiusProperty in PCL.
public class CustomFrame: Frame
{
public static new readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(nameof(CustomFrame), typeof(CornerRadius), typeof(CustomFrame));
public CustomFrame()
{
// MK Clearing default values (e.g. on iOS it's 5)
base.CornerRadius = 0;
}
public new CornerRadius CornerRadius
{
get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
}
在 Android 中创建 CustomFrameRender。
using FrameRenderer = Xamarin.Forms.Platform.Android.AppCompat.FrameRenderer; [assembly: ExportRenderer(typeof(CustomFrame), typeof(CustomFrameRenderer))] namespace Demo1.Droid { class CustomFrameRenderer : FrameRenderer { public CustomFrameRenderer(Context context) : base(context) { } protected override void OnElementChanged(ElementChangedEventArgs<Frame> e) { base.OnElementChanged(e); if (e.NewElement != null && Control != null) { UpdateCornerRadius(); } } protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); if (e.PropertyName == nameof(CustomFrame.CornerRadius) || e.PropertyName == nameof(CustomFrame)) { UpdateCornerRadius(); } } private void UpdateCornerRadius() { if (Control.Background is GradientDrawable backgroundGradient) { var cornerRadius = (Element as CustomFrame)?.CornerRadius; if (!cornerRadius.HasValue) { return; } var topLeftCorner = Context.ToPixels(cornerRadius.Value.TopLeft); var topRightCorner = Context.ToPixels(cornerRadius.Value.TopRight); var bottomLeftCorner = Context.ToPixels(cornerRadius.Value.BottomLeft); var bottomRightCorner = Context.ToPixels(cornerRadius.Value.BottomRight); var cornerRadii = new[] { topLeftCorner, topLeftCorner, topRightCorner, topRightCorner, bottomRightCorner, bottomRightCorner, bottomLeftCorner, bottomLeftCorner, }; backgroundGradient.SetCornerRadii(cornerRadii); } } } }
3.using 表单中的自定义框架。
<StackLayout>
<controls:CustomFrame
BackgroundColor="Red"
CornerRadius="0,30,0,0"
HeightRequest="100"
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="100" />
</StackLayout>
更详细的内容请参考:
这是针对 UWP 渲染器的
我使用了 Cherry Bu - MSFT 的解决方案并将其更改为 UWP。在我的项目中,我在 Android、iOS 和 UWP 中使用它并且工作正常。
using System.ComponentModel;
using Windows.UI.Xaml.Media;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
[assembly: ExportRenderer(typeof(CustomFrame), typeof(yourNamespace.UWP.CustomFrameRenderer))]
namespace yourNamespace.UWP
{
public class CustomFrameRenderer : FrameRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
if (e.NewElement != null && Control != null)
{
UpdateCornerRadius();
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == nameof(CustomFrame.CornerRadius) ||
e.PropertyName == nameof(CustomFrame))
{
UpdateCornerRadius();
}
}
private void UpdateCornerRadius()
{
var radius = ((CustomFrame)this.Element).CornerRadius;
Control.CornerRadius = new Windows.UI.Xaml.CornerRadius(radius.TopLeft, radius.TopRight, radius.BottomRight, radius.BottomLeft);
}
}
}
使用 nuget 包 Xamarin.Forms.PancakeView。
查看类似问题的答案:
我使用的简单解决方案是在圆形框架后面设置另一个框架,如下所示
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.05*"/>
<RowDefinition Height="0.05*"/>
<RowDefinition Height="0.8*"/>
<RowDefinition Height="0.05*"/>
<RowDefinition Height="0.05*"/>
</Grid.RowDefinitions>
<Frame
Grid.Row="4"
Padding="0"
BackgroundColor="Green"
CornerRadius="0"/>
<Frame
Grid.Row="3"
Grid.RowSpan="2"
Padding="0"
BackgroundColor="Green"
HasShadow="True"
CornerRadius="20">
</Frame>
</Grid>