diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/IconTintColorBehaviorPage.xaml b/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/IconTintColorBehaviorPage.xaml index 6ec36f63d6..47914bbaba 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/IconTintColorBehaviorPage.xaml +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/IconTintColorBehaviorPage.xaml @@ -13,7 +13,7 @@ diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/IconTintColorBehaviorPage.xaml.cs b/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/IconTintColorBehaviorPage.xaml.cs index 23f32e1def..ba092513c4 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/IconTintColorBehaviorPage.xaml.cs +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/IconTintColorBehaviorPage.xaml.cs @@ -1,3 +1,4 @@ +using CommunityToolkit.Maui.Behaviors; using CommunityToolkit.Maui.Sample.ViewModels.Behaviors; namespace CommunityToolkit.Maui.Sample.Pages.Behaviors; @@ -9,4 +10,23 @@ public IconTintColorBehaviorPage(IconTintColorBehaviorViewModel iconTintColorBeh { InitializeComponent(); } + + void HandleButtonClicked(object? sender, EventArgs e) + { + ArgumentNullException.ThrowIfNull(sender); + + var button = (Button)sender; + + if (button.Behaviors.OfType().SingleOrDefault() is IconTintColorBehavior iconTintColorBehavior) + { + button.Behaviors.Remove(iconTintColorBehavior); + } + else + { + button.Behaviors.Add(new IconTintColorBehavior + { + TintColor = Colors.Green + }); + } + } } \ No newline at end of file diff --git a/src/CommunityToolkit.Maui/Behaviors/PlatformBehaviors/IconTintColor/IconTintColorBehavior.android.cs b/src/CommunityToolkit.Maui/Behaviors/PlatformBehaviors/IconTintColor/IconTintColorBehavior.android.cs index 87884df2f1..4e0fe93a6e 100644 --- a/src/CommunityToolkit.Maui/Behaviors/PlatformBehaviors/IconTintColor/IconTintColorBehavior.android.cs +++ b/src/CommunityToolkit.Maui/Behaviors/PlatformBehaviors/IconTintColor/IconTintColorBehavior.android.cs @@ -2,8 +2,9 @@ using Android.Graphics; using Android.Widget; using Microsoft.Maui.Platform; -using AButton = Android.Widget.Button; -using AView = Android.Views.View; +using AndroidMaterialButton = Google.Android.Material.Button.MaterialButton; +using AndroidView = Android.Views.View; +using AndroidWidgetButton = Android.Widget.Button; using Color = Microsoft.Maui.Graphics.Color; using ImageButton = Microsoft.Maui.Controls.ImageButton; @@ -11,42 +12,33 @@ namespace CommunityToolkit.Maui.Behaviors; public partial class IconTintColorBehavior { - AView? nativeView; + AndroidView? nativeView; /// - protected override void OnAttachedTo(View bindable, AView platformView) + protected override void OnAttachedTo(View bindable, AndroidView platformView) { base.OnAttachedTo(bindable, platformView); nativeView = platformView; - ApplyTintColor(); + ApplyTintColor(nativeView, TintColor); bindable.PropertyChanged += OnElementPropertyChanged; PropertyChanged += OnTintedImagePropertyChanged; } - void OnTintedImagePropertyChanged(object? sender, PropertyChangedEventArgs e) - { - if (e.PropertyName == TintColorProperty.PropertyName) - { - ApplyTintColor(); - } - } - /// - protected override void OnDetachedFrom(View bindable, AView platformView) + protected override void OnDetachedFrom(View bindable, AndroidView platformView) { base.OnDetachedFrom(bindable, platformView); ClearTintColor(bindable, platformView); + bindable.PropertyChanged -= OnElementPropertyChanged; PropertyChanged -= OnTintedImagePropertyChanged; } - void ApplyTintColor() + static void ApplyTintColor(AndroidView? nativeView, Color? tintColor) { - var color = TintColor; - if (nativeView is null) { return; @@ -55,11 +47,17 @@ void ApplyTintColor() switch (nativeView) { case ImageView image: - SetImageViewTintColor(image, color); + SetImageViewTintColor(image, tintColor); + break; + + case AndroidMaterialButton materialButton when tintColor is not null: + SetMaterialButtonTintColor(materialButton, tintColor); break; - case AButton button: - SetButtonTintColor(button, color); + + case AndroidWidgetButton widgetButton: + SetWidgetButtonTintColor(widgetButton, tintColor); break; + default: throw new NotSupportedException($"{nameof(IconTintColorBehavior)} only currently supports Android.Widget.Button and {nameof(ImageView)}."); } @@ -76,9 +74,18 @@ static void SetImageViewTintColor(ImageView image, Color? color) image.SetColorFilter(new PorterDuffColorFilter(color.ToPlatform(), PorterDuff.Mode.SrcIn ?? throw new InvalidOperationException("PorterDuff.Mode.SrcIn should not be null at runtime."))); } - static void SetButtonTintColor(AButton button, Color? color) + static void SetMaterialButtonTintColor(AndroidMaterialButton button, Color color) + { + button.IconTintMode = PorterDuff.Mode.SrcIn; + button.IconTint = new Android.Content.Res.ColorStateList(new int[][] + { + [] + }, [color.ToPlatform()]); + } + + static void SetWidgetButtonTintColor(AndroidWidgetButton button, Color? color) { - var drawables = button.GetCompoundDrawables().Where(d => d is not null); + var drawables = button.GetCompoundDrawables().ToList(); if (color is null) { @@ -96,11 +103,33 @@ static void SetButtonTintColor(AButton button, Color? color) } } + static void ClearTintColor(View element, AndroidView control) + { + switch (control) + { + case ImageView image: + image.ClearColorFilter(); + break; + + case AndroidMaterialButton mButton: + mButton.IconTint = null; + break; + + case AndroidWidgetButton button: + foreach (var drawable in button.GetCompoundDrawables()) + { + drawable.ClearColorFilter(); + } + + break; + } + } + void OnElementPropertyChanged(object? sender, PropertyChangedEventArgs args) { if (args.PropertyName is not string propertyName || sender is not View bindable - || bindable.Handler?.PlatformView is not AView platformView) + || bindable.Handler?.PlatformView is not AndroidView) { return; } @@ -111,22 +140,14 @@ void OnElementPropertyChanged(object? sender, PropertyChangedEventArgs args) return; } - ApplyTintColor(); + ApplyTintColor(nativeView, TintColor); } - void ClearTintColor(View element, AView control) + void OnTintedImagePropertyChanged(object? sender, PropertyChangedEventArgs e) { - switch (control) + if (e.PropertyName == TintColorProperty.PropertyName) { - case ImageView image: - image.ClearColorFilter(); - break; - case AButton button: - foreach (var drawable in button.GetCompoundDrawables()) - { - drawable?.ClearColorFilter(); - } - break; + ApplyTintColor(nativeView, TintColor); } } } \ No newline at end of file diff --git a/src/CommunityToolkit.Maui/Behaviors/PlatformBehaviors/IconTintColor/IconTintColorBehavior.windows.cs b/src/CommunityToolkit.Maui/Behaviors/PlatformBehaviors/IconTintColor/IconTintColorBehavior.windows.cs index 6e0bc6d35b..d29d27dedb 100644 --- a/src/CommunityToolkit.Maui/Behaviors/PlatformBehaviors/IconTintColor/IconTintColorBehavior.windows.cs +++ b/src/CommunityToolkit.Maui/Behaviors/PlatformBehaviors/IconTintColor/IconTintColorBehavior.windows.cs @@ -55,7 +55,13 @@ protected override void OnDetachedFrom(View bindable, FrameworkElement platformV static bool TryGetButtonImage(WButton button, [NotNullWhen(true)] out WImage? image) { - image = button.Content as WImage; + image = button.Content switch + { + WImage windowsImage => windowsImage, + Microsoft.UI.Xaml.Controls.Panel panel => panel.Children?.OfType().FirstOrDefault(), + _ => null + }; + return image is not null; }