android [Xamarin.Forms] 中独特角半径值的自定义帧渲染器
Custom Frame renderer for unique corner radius values in android [Xamarin.Forms]
我想为我的框架控件创建一个自定义渲染器,事实上我有一个每个角半径值都是唯一的控件,我已经尝试通过多种方式为框架控件创建一个自定义渲染器,但我还没有找到一个 "solid" 解决方案,我的自定义渲染器不工作,我也尝试使用 Xamarin.Forms.PancackeView 插件但是在我的 Xamarin.Forms 版本(4.3.0.991)中它似乎有一个错误或相关内容:
额外:
我想在控件框架中实现阴影,但你应该知道,框架控件默认有阴影,但我的框架中的阴影不起作用,是否有错误或如何将阴影实现到自定义框架渲染器?
Android 自定义帧渲染器代码:
[assembly: ExportRenderer(typeof(TagFrame), typeof(TagFrameCustomRendererAndroid))]
namespace Sortex.Droid.CRImplementations
{
public class TagFrameCustomRendererAndroid : FrameRenderer
{
public TagFrameCustomRendererAndroid(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
GradientDrawable gradientDrawable = new GradientDrawable();
float[] cornerRadius = { 100000, 100000, 0, 0, 0, 0, 100000, 100000 };
gradientDrawable.SetCornerRadii(cornerRadius);
SetBackgroundDrawable(gradientDrawable);
}
}
}
}
共享项目中的 TagFrame class:
public class TagFrame : Frame
{
}
I want to create a custom renderer for my frame control in fact of having a control which each corner radius values are unique,
根据您的描述,您想要自定义渲染帧,那么您可以设置不同的圆角半径。如果是,我做了一个样例,你可以看看:
首先,创建CustomFrame继承Frame,具有BindableProperty CornerRadiusProperty。
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平台,
using FrameRenderer = Xamarin.Forms.Platform.Android.AppCompat.FrameRenderer;
[assembly: ExportRenderer(typeof(CustomFrame), typeof(CustomFrameRenderer))]
namespace Framerender.Droid
{
public 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);
}
}
}
}
现在,您可以在 PCL 中使用 CustomFrame。
<local:CustomFrame
BackgroundColor="Red"
CornerRadius="0,0,30,30"
HasShadow="True"
HeightRequest="100"
VerticalOptions="CenterAndExpand"
WidthRequest="100" />
这里是Github的例子,你也可以看看:
https://github.com/CherryBu/CustomFrame
还有一篇关于customframe的文章:
我想为我的框架控件创建一个自定义渲染器,事实上我有一个每个角半径值都是唯一的控件,我已经尝试通过多种方式为框架控件创建一个自定义渲染器,但我还没有找到一个 "solid" 解决方案,我的自定义渲染器不工作,我也尝试使用 Xamarin.Forms.PancackeView 插件但是在我的 Xamarin.Forms 版本(4.3.0.991)中它似乎有一个错误或相关内容:
额外: 我想在控件框架中实现阴影,但你应该知道,框架控件默认有阴影,但我的框架中的阴影不起作用,是否有错误或如何将阴影实现到自定义框架渲染器?
Android 自定义帧渲染器代码:
[assembly: ExportRenderer(typeof(TagFrame), typeof(TagFrameCustomRendererAndroid))]
namespace Sortex.Droid.CRImplementations
{
public class TagFrameCustomRendererAndroid : FrameRenderer
{
public TagFrameCustomRendererAndroid(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
GradientDrawable gradientDrawable = new GradientDrawable();
float[] cornerRadius = { 100000, 100000, 0, 0, 0, 0, 100000, 100000 };
gradientDrawable.SetCornerRadii(cornerRadius);
SetBackgroundDrawable(gradientDrawable);
}
}
}
}
共享项目中的 TagFrame class:
public class TagFrame : Frame
{
}
I want to create a custom renderer for my frame control in fact of having a control which each corner radius values are unique,
根据您的描述,您想要自定义渲染帧,那么您可以设置不同的圆角半径。如果是,我做了一个样例,你可以看看:
首先,创建CustomFrame继承Frame,具有BindableProperty CornerRadiusProperty。
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平台,
using FrameRenderer = Xamarin.Forms.Platform.Android.AppCompat.FrameRenderer;
[assembly: ExportRenderer(typeof(CustomFrame), typeof(CustomFrameRenderer))]
namespace Framerender.Droid
{
public 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);
}
}
}
}
现在,您可以在 PCL 中使用 CustomFrame。
<local:CustomFrame
BackgroundColor="Red"
CornerRadius="0,0,30,30"
HasShadow="True"
HeightRequest="100"
VerticalOptions="CenterAndExpand"
WidthRequest="100" />
这里是Github的例子,你也可以看看:
https://github.com/CherryBu/CustomFrame
还有一篇关于customframe的文章: