【问题标题】:Xamarin Forms Android custom frame renderer makes corners rectangularXamarin Forms Android 自定义框架渲染器使角落变成矩形
【发布时间】:2021-06-30 15:59:41
【问题描述】:

我正在使用 Xamarin Forms 版本 5.0.0.2012 和 Visual Studio 16.10.2。 我想在 Xamarin Forms Android 应用程序中使用自定义渲染器来获得自定义阴影。当我使用普通框架时,角落是圆的,但我对阴影不满意。当我使用自定义框架时,应用程序将框架角和阴影渲染为矩形(看起来很糟糕)。

[assembly: ExportRenderer(typeof(CustomFrame), typeof(CustomFrameRenderer))]
namespace SimpleApp.Droid.CustomControlRenderers
{
    public class CustomFrameRenderer : FrameRenderer
    {
        Context context;
        public CustomFrameRenderer(Context context) : base(context)
        {
            this.context = context;
        }

        protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Frame> e)
        {
            base.OnElementChanged(e);
                var element = e.NewElement as CustomFrame;
                if (element == null) return;

                if (element.HasStrongShadow)
                {
                    Elevation = 50.0f;
                    var strongShadowColor = Xamarin.Forms.Platform.Android.ColorExtensions.ToAndroid(element.StrongShadowColor);
                    var lightGrayColor = Android.Graphics.Color.Rgb(206, 208, 210);
                    SetOutlineSpotShadowColor(lightGrayColor);
                    SetOutlineAmbientShadowColor(strongShadowColor);
                }
        }
    }
}

HasStrongShadow 是我的自定义属性。 我应该怎么做才能同时使用圆角和自定义渲染器?

【问题讨论】:

    标签: xamarin xamarin.forms


    【解决方案1】:

    我应该怎么做才能有圆角并使用自定义渲染器 同一时间?

    您可以在 CustomFrame 中定义属性 CornerRadius

    请参考以下代码:

    1.在表单中定义一个自定义框架(CustomFrame):

    CustomFrame.cs

    public class CustomFrame: Frame
    {
        public new static 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);
        }
    }
    

    2.在android中创建类CustomFrameRenderer

    using System.ComponentModel;
    using Android.Content;
    using Android.Graphics.Drawables;
    using FrameRendererApp;
    using FrameRendererApp.Droid;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.Android;
    using FrameRenderer = Xamarin.Forms.Platform.Android.AppCompat.FrameRenderer;
    
    [assembly: ExportRenderer(typeof(CustomFrame), typeof(CustomFrameRenderer))]
    namespace FrameRendererApp.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);
                }
            }
        }
    }
    

    3.用法:

        <framerendererapp:CustomFrame
              CornerRadius="30,30,30,30"
              HasShadow="True"
                        BackgroundColor="Red"
                        HorizontalOptions="Center"
                        VerticalOptions="Center"
                        HeightRequest="100"
                        WidthRequest="100">
        </framerendererapp:CustomFrame>
    

    结果是:

    【讨论】:

    • 谢谢,但此解决方案(自定义渲染器)适用于 Xamarin Forms 3.6,并且不与最新的 Xamarin Forms 5.0 合作。对我来说,这是 Xamarin Forms 库中的一个错误。我正在寻找解决方法。
    • 我的demo中xamarin form nuget的版本是5.0.0.2012,也是目前最新的稳定版本。
    猜你喜欢
    • 2018-07-23
    • 1970-01-01
    • 2018-07-29
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    • 2021-06-18
    • 1970-01-01
    相关资源
    最近更新 更多