diff options
Diffstat (limited to 'Xamarin.Forms.Platform.Android/Renderers/FrameRenderer.cs')
-rw-r--r-- | Xamarin.Forms.Platform.Android/Renderers/FrameRenderer.cs | 195 |
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 |