summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.Android/Renderers/FrameRenderer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Platform.Android/Renderers/FrameRenderer.cs')
-rw-r--r--Xamarin.Forms.Platform.Android/Renderers/FrameRenderer.cs195
1 files changed, 195 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.Android/Renderers/FrameRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/FrameRenderer.cs
new file mode 100644
index 00000000..63fb5da4
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Renderers/FrameRenderer.cs
@@ -0,0 +1,195 @@
+using System.ComponentModel;
+using Android.Graphics;
+using Android.Graphics.Drawables;
+using AButton = Android.Widget.Button;
+using ACanvas = Android.Graphics.Canvas;
+using GlobalResource = Android.Resource;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public class FrameRenderer : VisualElementRenderer<Frame>
+ {
+ bool _disposed;
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ if (disposing && !_disposed)
+ {
+ Background.Dispose();
+ _disposed = true;
+ }
+ }
+
+ protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
+ {
+ base.OnElementChanged(e);
+
+ if (e.NewElement != null && e.OldElement == null)
+ UpdateBackground();
+ }
+
+ void UpdateBackground()
+ {
+ SetBackgroundDrawable(new FrameDrawable(Element));
+ }
+
+ class FrameDrawable : Drawable
+ {
+ readonly Frame _frame;
+
+ bool _isDisposed;
+ Bitmap _normalBitmap;
+
+ public FrameDrawable(Frame frame)
+ {
+ _frame = frame;
+ frame.PropertyChanged += FrameOnPropertyChanged;
+ }
+
+ public override bool IsStateful
+ {
+ get { return false; }
+ }
+
+ public override int Opacity
+ {
+ get { return 0; }
+ }
+
+ public override void Draw(ACanvas canvas)
+ {
+ int width = Bounds.Width();
+ int height = Bounds.Height();
+
+ if (width <= 0 || height <= 0)
+ {
+ if (_normalBitmap != null)
+ {
+ _normalBitmap.Dispose();
+ _normalBitmap = null;
+ }
+ return;
+ }
+
+ if (_normalBitmap == null || _normalBitmap.Height != height || _normalBitmap.Width != width)
+ {
+ // If the user changes the orientation of the screen, make sure to detroy reference before
+ // reassigning a new bitmap reference.
+ if (_normalBitmap != null)
+ {
+ _normalBitmap.Dispose();
+ _normalBitmap = null;
+ }
+
+ _normalBitmap = CreateBitmap(false, width, height);
+ }
+ Bitmap bitmap = _normalBitmap;
+ using(var paint = new Paint())
+ canvas.DrawBitmap(bitmap, 0, 0, paint);
+ }
+
+ public override void SetAlpha(int alpha)
+ {
+ }
+
+ public override void SetColorFilter(ColorFilter cf)
+ {
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && !_isDisposed)
+ {
+ if (_normalBitmap != null)
+ {
+ _normalBitmap.Dispose();
+ _normalBitmap = null;
+ }
+
+ _isDisposed = true;
+ }
+
+ base.Dispose(disposing);
+ }
+
+ protected override bool OnStateChange(int[] state)
+ {
+ return false;
+ }
+
+ Bitmap CreateBitmap(bool pressed, int width, int height)
+ {
+ Bitmap bitmap;
+ using(Bitmap.Config config = Bitmap.Config.Argb8888)
+ bitmap = Bitmap.CreateBitmap(width, height, config);
+
+ using(var canvas = new ACanvas(bitmap))
+ {
+ DrawBackground(canvas, width, height, pressed);
+ DrawOutline(canvas, width, height);
+ }
+
+ return bitmap;
+ }
+
+ void DrawBackground(ACanvas canvas, int width, int height, bool pressed)
+ {
+ using(var paint = new Paint { AntiAlias = true })
+ using(var path = new Path())
+ using(Path.Direction direction = Path.Direction.Cw)
+ using(Paint.Style style = Paint.Style.Fill)
+ using(var rect = new RectF(0, 0, width, height))
+ {
+ float rx = Forms.Context.ToPixels(5);
+ float ry = Forms.Context.ToPixels(5);
+ path.AddRoundRect(rect, rx, ry, direction);
+
+ global::Android.Graphics.Color color = _frame.BackgroundColor.ToAndroid();
+
+ paint.SetStyle(style);
+ paint.Color = color;
+
+ canvas.DrawPath(path, paint);
+ }
+ }
+
+ void DrawOutline(ACanvas canvas, int width, int height)
+ {
+ using(var paint = new Paint { AntiAlias = true })
+ using(var path = new Path())
+ using(Path.Direction direction = Path.Direction.Cw)
+ using(Paint.Style style = Paint.Style.Stroke)
+ using(var rect = new RectF(0, 0, width, height))
+ {
+ float rx = Forms.Context.ToPixels(5);
+ float ry = Forms.Context.ToPixels(5);
+ path.AddRoundRect(rect, rx, ry, direction);
+
+ paint.StrokeWidth = 1;
+ paint.SetStyle(style);
+ paint.Color = _frame.OutlineColor.ToAndroid();
+
+ canvas.DrawPath(path, paint);
+ }
+ }
+
+ void FrameOnPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName || e.PropertyName == Frame.OutlineColorProperty.PropertyName)
+ {
+ using(var canvas = new ACanvas(_normalBitmap))
+ {
+ int width = Bounds.Width();
+ int height = Bounds.Height();
+ canvas.DrawColor(global::Android.Graphics.Color.Black, PorterDuff.Mode.Clear);
+ DrawBackground(canvas, width, height, false);
+ DrawOutline(canvas, width, height);
+ }
+ InvalidateSelf();
+ }
+ }
+ }
+ }
+} \ No newline at end of file