自定义帧渲染器,用于Android [Xamarin.Forms]中唯一的拐角半径值

时间:2020-01-30 22:58:53

标签: android xamarin xamarin.forms xamarin.android renderer

实际上,我想为我的框架控件创建一个自定义渲染器,实际上,每个控件的每个拐角半径值都是唯一的,我试图通过多种方式为框架控件创建一个自定义渲染器,但是我没有找到“ “固体”解决方案,我的自定义渲染器无法正常工作,我也尝试过使用Xamarin.Forms.PancackeView插件,但是在我的Xamarin.Forms版本(4.3.0.991)中,似乎有错误或其他相关问题:

额外: 我想在控制框架中实现阴影,但是如您所知,框架控件默认情况下具有阴影,但是框架中的阴影不起作用,是否存在错误或如何对自定义框架渲染器实施阴影? / p>

用于自定义框架渲染器的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类:

public class TagFrame : Frame
{
}

1 个答案:

答案 0 :(得分:0)

事实上,我想为我的框架控件创建一个自定义渲染器,因为每个控件的每个拐角半径值都是唯一的,

根据您的描述,您要自定义渲染框架,然后可以设置不同的拐角半径。如果是,那么我做一个样本,您可以看一下:

首先,创建CustomFrame继承框架,具有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;

[程序集:ExportRenderer(typeof(CustomFrame),typeof(CustomFrameRenderer))] 命名空间Framerender.Droid { 公共类CustomFrameRenderer:FrameRenderer { 公共CustomFrameRenderer(上下文上下文) :基础(上下文) { }

    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的文章:

https://progrunning.net/customizing-corner-radius/