From ffa6e56d98cf7662964aa0c0cc65cd1ec45065f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Su=C3=A1rez=20Ruiz?= Date: Mon, 11 Apr 2022 13:09:52 +0200 Subject: [PATCH 1/2] Fix issues rendering gradients and corner radius on Android Button --- .../Handlers/Button/ButtonHandler.Android.cs | 12 +-- .../src/Platform/Android/BorderDrawable.cs | 52 ++++++----- .../src/Platform/Android/ButtonExtensions.cs | 86 ++++++++++++++++--- .../src/Platform/Android/ViewExtensions.cs | 8 +- 4 files changed, 108 insertions(+), 50 deletions(-) diff --git a/src/Core/src/Handlers/Button/ButtonHandler.Android.cs b/src/Core/src/Handlers/Button/ButtonHandler.Android.cs index 629c31d83bfa..acfa7964413b 100644 --- a/src/Core/src/Handlers/Button/ButtonHandler.Android.cs +++ b/src/Core/src/Handlers/Button/ButtonHandler.Android.cs @@ -69,19 +69,19 @@ public static void MapBackground(IButtonHandler handler, IButton button) handler.PlatformView?.UpdateBackground(button); } - public static void MapStrokeColor(IButtonHandler handler, IButtonStroke buttonStroke) + public static void MapStrokeColor(IButtonHandler handler, IButton button) { - handler.PlatformView?.UpdateStrokeColor(buttonStroke); + handler.PlatformView?.UpdateStrokeColor(button); } - public static void MapStrokeThickness(IButtonHandler handler, IButtonStroke buttonStroke) + public static void MapStrokeThickness(IButtonHandler handler, IButton button) { - handler.PlatformView?.UpdateStrokeThickness(buttonStroke); + handler.PlatformView?.UpdateStrokeThickness(button); } - public static void MapCornerRadius(IButtonHandler handler, IButtonStroke buttonStroke) + public static void MapCornerRadius(IButtonHandler handler, IButton button) { - handler.PlatformView?.UpdateCornerRadius(buttonStroke); + handler.PlatformView?.UpdateCornerRadius(button); } public static void MapText(IButtonHandler handler, IText button) diff --git a/src/Core/src/Platform/Android/BorderDrawable.cs b/src/Core/src/Platform/Android/BorderDrawable.cs index 1f2e75b7dc8a..68020b7aac0c 100644 --- a/src/Core/src/Platform/Android/BorderDrawable.cs +++ b/src/Core/src/Platform/Android/BorderDrawable.cs @@ -267,11 +267,11 @@ protected override void OnDraw(Shape? shape, Canvas? canvas, APaint? paint) if (_disposed) return; + if (Paint != null) + SetBackground(Paint); + if (HasBorder()) { - if (Paint != null) - SetBackground(Paint); - if (_borderPaint != null) { _borderPaint.StrokeWidth = _strokeThickness; @@ -284,44 +284,40 @@ protected override void OnDraw(Shape? shape, Canvas? canvas, APaint? paint) SetPaint(_borderPaint, _stroke); } } + } - if (_invalidatePath) - { - _invalidatePath = false; + if (_invalidatePath) + { + _invalidatePath = false; - var path = GetPath(_width, _height, _cornerRadius, _strokeThickness); - var clipPath = path?.AsAndroidPath(); + var path = GetPath(_width, _height, _cornerRadius, _strokeThickness); + var clipPath = path?.AsAndroidPath(); - if (clipPath == null) - return; + if (clipPath == null) + return; - if (_clipPath != null) - { - _clipPath.Reset(); - _clipPath.Set(clipPath); - } + if (_clipPath != null) + { + _clipPath.Reset(); + _clipPath.Set(clipPath); } + } - if (canvas == null) - return; + if (canvas == null) + return; - var saveCount = canvas.SaveLayer(0, 0, _width, _height, null); + var saveCount = canvas.SaveLayer(0, 0, _width, _height, null); - if (_clipPath != null && Paint != null) - canvas.DrawPath(_clipPath, Paint); + if (_clipPath != null && Paint != null) + canvas.DrawPath(_clipPath, Paint); + if (HasBorder()) + { if (_clipPath != null && _borderPaint != null) canvas.DrawPath(_clipPath, _borderPaint); - - canvas.RestoreToCount(saveCount); } - else - { - if (paint != null) - SetBackground(paint); - base.OnDraw(shape, canvas, paint); - } + canvas.RestoreToCount(saveCount); } protected override void Dispose(bool disposing) diff --git a/src/Core/src/Platform/Android/ButtonExtensions.cs b/src/Core/src/Platform/Android/ButtonExtensions.cs index b630f51dc53f..66efe868ae5c 100644 --- a/src/Core/src/Platform/Android/ButtonExtensions.cs +++ b/src/Core/src/Platform/Android/ButtonExtensions.cs @@ -6,22 +6,50 @@ namespace Microsoft.Maui.Platform { public static class ButtonExtensions { - public static void UpdateStrokeColor(this MaterialButton platformButton, IButtonStroke buttonStroke) + public static void UpdateBackground(this MaterialButton platformView, IButton button) { - if (buttonStroke.StrokeColor is Color stroke) - platformButton.StrokeColor = ColorStateListExtensions.CreateButton(stroke.ToPlatform()); + var background = button.Background; + + if (background is SolidPaint) + platformView.UpdateBackground(background); + else + platformView.UpdateBorderDrawable(button); } - public static void UpdateStrokeThickness(this MaterialButton platformButton, IButtonStroke buttonStroke) + public static void UpdateStrokeColor(this MaterialButton platformView, IButton button) { - if (buttonStroke.StrokeThickness >= 0) - platformButton.StrokeWidth = (int)platformButton.Context.ToPixels(buttonStroke.StrokeThickness); + if (platformView.Background is BorderDrawable) + { + platformView.UpdateBorderDrawable(button); + return; + } + + if (button is IButtonStroke buttonStroke && buttonStroke.StrokeColor is Color stroke) + platformView.StrokeColor = ColorStateListExtensions.CreateButton(stroke.ToPlatform()); } - public static void UpdateCornerRadius(this MaterialButton platformButton, IButtonStroke buttonStroke) + public static void UpdateStrokeThickness(this MaterialButton platformView, IButton button) { - if (buttonStroke.CornerRadius >= 0) - platformButton.CornerRadius = (int)platformButton.Context.ToPixels(buttonStroke.CornerRadius); + if (platformView.Background is BorderDrawable) + { + platformView.UpdateBorderDrawable(button); + return; + } + + if (button is IButtonStroke buttonStroke && buttonStroke.StrokeThickness >= 0) + platformView.StrokeWidth = (int)platformView.Context.ToPixels(buttonStroke.StrokeThickness); + } + + public static void UpdateCornerRadius(this MaterialButton platformView, IButton button) + { + if (platformView.Background is BorderDrawable) + { + platformView.UpdateBorderDrawable(button); + return; + } + + if (button is IButtonStroke buttonStroke && buttonStroke.CornerRadius >= 0) + platformView.CornerRadius = (int)platformView.Context.ToPixels(buttonStroke.CornerRadius); } public static void UpdatePadding(this Button platformControl, IPadding padding, Thickness? defaultPadding = null) => @@ -44,10 +72,48 @@ public static void UpdatePadding(this Button platformControl, Thickness padding, (int)padding.Right, (int)padding.Bottom); } - + public static void UpdateLineBreakMode(this Button nativeControl, ILineBreakMode button) { nativeControl.SetLineBreakMode(button); } + + internal static void UpdateBorderDrawable(this MaterialButton platformView, IButton button) + { + var background = button.Background; + + if (!background.IsNullOrEmpty()) + { + // Remove previous background gradient if any + if (platformView.Background is BorderDrawable previousBackground) + { + platformView.Background = null; + previousBackground.Dispose(); + } + + var mauiDrawable = new BorderDrawable(platformView.Context); + + // Null out BackgroundTintList to avoid that the MaterialButton custom background doesn't get tinted. + platformView.BackgroundTintList = null; + + platformView.Background = mauiDrawable; + + mauiDrawable.SetBackground(background); + + if (button.StrokeColor != null) + mauiDrawable.SetBorderBrush(new SolidPaint { Color = button.StrokeColor }); + + if (button.StrokeThickness > 0) + mauiDrawable.SetBorderWidth(button.StrokeThickness); + + if (button.CornerRadius > 0) + mauiDrawable.SetCornerRadius(button.CornerRadius); + else + { + const int defaultCornerRadius = 2; // Default value for Android material button. + mauiDrawable.SetCornerRadius(platformView.Context.ToPixels(defaultCornerRadius)); + } + } + } } } \ No newline at end of file diff --git a/src/Core/src/Platform/Android/ViewExtensions.cs b/src/Core/src/Platform/Android/ViewExtensions.cs index e91ed9f7b7bc..92660bcd3e73 100644 --- a/src/Core/src/Platform/Android/ViewExtensions.cs +++ b/src/Core/src/Platform/Android/ViewExtensions.cs @@ -1,6 +1,5 @@ using System; using System.Numerics; -using System.Threading.Tasks; using Android.Content; using Android.Graphics.Drawables; using Android.OS; @@ -8,16 +7,11 @@ using Android.Views; using Android.Widget; using AndroidX.Core.Content; -using AndroidX.Core.View; using Microsoft.Maui.ApplicationModel; -using Microsoft.Maui.Devices; using Microsoft.Maui.Graphics; -using Microsoft.Maui.Handlers; -using Microsoft.Maui.Media; using Microsoft.Maui.Primitives; using AColor = Android.Graphics.Color; using ALayoutDirection = Android.Views.LayoutDirection; -using ATextDirection = Android.Views.TextDirection; using AView = Android.Views.View; using GL = Android.Opengl; @@ -186,6 +180,7 @@ public static void UpdateBackground(this AView platformView, Paint? background) platformView.Background = null; mauiDrawable.Dispose(); } + if (paint is SolidPaint solidPaint) { if (solidPaint.Color is Color backgroundColor) @@ -310,6 +305,7 @@ public static void RemoveFromParent(this AView view) internal static Rect GetPlatformViewBounds(this IView view) { var platformView = view?.ToPlatform(); + if (platformView?.Context == null) { return new Rect(); From 0ccf67d651791f3138a515201071d31f937c4a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Su=C3=A1rez=20Ruiz?= Date: Tue, 26 Apr 2022 13:12:03 +0200 Subject: [PATCH 2/2] Fix build errors --- src/Core/src/Platform/Android/ButtonExtensions.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Core/src/Platform/Android/ButtonExtensions.cs b/src/Core/src/Platform/Android/ButtonExtensions.cs index 66efe868ae5c..c99ee867f32e 100644 --- a/src/Core/src/Platform/Android/ButtonExtensions.cs +++ b/src/Core/src/Platform/Android/ButtonExtensions.cs @@ -73,11 +73,6 @@ public static void UpdatePadding(this Button platformControl, Thickness padding, (int)padding.Bottom); } - public static void UpdateLineBreakMode(this Button nativeControl, ILineBreakMode button) - { - nativeControl.SetLineBreakMode(button); - } - internal static void UpdateBorderDrawable(this MaterialButton platformView, IButton button) { var background = button.Background;