Reputation: 367
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);
}
}
}
Upvotes: 2
Views: 3496
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>
if not working, then check below answer too
Upvotes: 0
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