David
David

Reputation: 367

How can I show shadows on the edges of my Frame in Xamarin.forms?

Currently I want the edges of my frame element to be shown shaded in Xamarin XAML, use the HasShadow attribute of the Frame element but it did not work or mark a difference, then I will render a custom frame and if it comes out but it is not a shading it puts it as a second line, I use Android 7.

Codigo XAML:

        <localframe:MyFrame 
           HasShadow="True" 
           ShadowColor="Red" 
           BorderColor="Red"
           BorderWidth="10"/>

Code Frame:

public class MyFrame:Frame
    {

        public static readonly BindableProperty ShadowColorProperty = BindableProperty.Create(nameof(ShadowColor), typeof(Color), typeof(MyFrame), Color.Transparent);
        public static readonly BindableProperty BorderWidthProperty = BindableProperty.Create(nameof(BorderWidth), typeof(float), typeof(MyFrame));

        public Color ShadowColor
        {
            get { return (Color)GetValue(ShadowColorProperty); }
            set { SetValue(ShadowColorProperty, value); }
        }


        public float BorderWidth
        {
            get { return (float)GetValue(BorderWidthProperty); }
            set { SetValue(BorderWidthProperty, value); }
        }

    }

Code Render Frame in Android:

[assembly: ExportRenderer(typeof(MyFrame), typeof(FrameRendererMy))]
namespace xxxxxxxxxx.Droid
{
    [Obsolete]
    public class FrameRendererMy : FrameRenderer
    {

        public FrameRendererMy(Context context) : base(context)
        {

        }


        protected override void OnDraw(Canvas canvas)
        {

            var frame = Element as MyFrame;

            var my1stPaint = new Android.Graphics.Paint();
            var my2ndPaint = new Android.Graphics.Paint();
            var backgroundPaint = new Android.Graphics.Paint();

            my1stPaint.AntiAlias = true;
            my1stPaint.SetStyle(Paint.Style.Stroke);
            my1stPaint.StrokeWidth = frame.BorderWidth + 2;
            my1stPaint.Color = frame.BorderColor.ToAndroid();

            my2ndPaint.AntiAlias = true;
            my2ndPaint.SetStyle(Paint.Style.Stroke);
            my2ndPaint.StrokeWidth = frame.BorderWidth;
            my2ndPaint.Color = frame.BackgroundColor.ToAndroid();

            backgroundPaint.SetStyle(Paint.Style.Stroke);
            backgroundPaint.StrokeWidth = 4;
            backgroundPaint.Color = frame.BackgroundColor.ToAndroid();

            Rect oldBounds = new Rect();
            canvas.GetClipBounds(oldBounds);

            RectF oldOutlineBounds = new RectF();
            oldOutlineBounds.Set(oldBounds);

            RectF myOutlineBounds = new RectF();
            myOutlineBounds.Set(oldBounds);
            myOutlineBounds.Top += (int)my2ndPaint.StrokeWidth + 3;
            myOutlineBounds.Bottom -= (int)my2ndPaint.StrokeWidth + 3;
            myOutlineBounds.Left += (int)my2ndPaint.StrokeWidth + 3;
            myOutlineBounds.Right -= (int)my2ndPaint.StrokeWidth + 3;


            canvas.DrawRoundRect(oldOutlineBounds, 10, 10, backgroundPaint); //to "hide" old outline
            canvas.DrawRoundRect(myOutlineBounds, frame.CornerRadius, frame.CornerRadius, my1stPaint);
            canvas.DrawRoundRect(myOutlineBounds, frame.CornerRadius, frame.CornerRadius, my2ndPaint);

            base.OnDraw(canvas);
        }


    }
}

enter image description here

Upvotes: 2

Views: 3496

Answers (2)

Supun Liyanaarachchi
Supun Liyanaarachchi

Reputation: 549

Try this code

    <StackLayout Margin="10">
    <Frame  CornerRadius="5"  Padding="8" HasShadow="True" Margin="10">
        <StackLayout>
            <Label Text="Frame Example" FontSize="Medium"  FontAttributes="Bold" />
            <BoxView Color="Gray" HeightRequest="2" HorizontalOptions="Fill" />
            <Label Text="Frames can wrap more complex layouts"/>
        </StackLayout>
    </Frame>
</StackLayout>

enter image description here

if not working, then check below answer too

Upvotes: 0

ottermatic
ottermatic

Reputation: 1012

I believe this is an existing issue in Xamarin.Forms. They also mention the Android issue in this thread HasShadow has no effect on Android.

you can use PancakeView which is a very nice and fully featured alternative to Frame.

Upvotes: 2

Related Questions