From 2e6bc92583222130607f62b5a19997f70fbcc66a Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Wed, 27 Feb 2019 16:48:45 -0700 Subject: [PATCH] [Visual] Visual tidy (#5356) * [Visual] remove visual flag and tidy up code * - added basic loading ui test * change material namespaces to be Xamarin.Forms.Material. * api 19 fixes * fix casing on resources --- .../FormsAppCompatActivity.cs | 4 +- Xamarin.Forms.ControlGallery.iOS/AppDelegate.cs | 2 +- .../VisualControlsPage.xaml | 2 +- .../VisualControlsPage.xaml.cs | 114 +++++++++++++++++++ .../Xamarin.Forms.Controls.Issues.Shared.projitems | 13 +++ .../ControlGalleryPages/VisualGallery.cs | 17 +++ .../ControlGalleryPages/VisualGallery.xaml.cs | 55 --------- .../UITestCategories.cs | 1 + Xamarin.Forms.Core.UnitTests/FlowDirectionTests.cs | 2 +- Xamarin.Forms.Core.UnitTests/RegistrarUnitTests.cs | 1 - Xamarin.Forms.Core.UnitTests/VisualTests.cs | 2 +- Xamarin.Forms.Core/ExperimentalFlags.cs | 1 - Xamarin.Forms.Core/Registrar.cs | 3 - Xamarin.Forms.Core/VisualElement.cs | 11 -- .../IMaterialEntryRenderer.cs | 2 +- Xamarin.Forms.Material.iOS/IMaterialTextField.cs | 13 +++ .../MaterialActivityIndicatorRenderer.cs | 16 +-- .../MaterialButtonRenderer.cs | 41 +------ .../MaterialDatePickerRenderer.cs | 41 ++----- .../MaterialEditorRenderer.cs | 37 ++----- .../MaterialEntryRenderer.cs | 42 ++----- .../MaterialFrameRenderer.cs | 123 +++++++++------------ .../MaterialMultiLineTextField.cs | 35 +++--- .../MaterialPickerRenderer.cs | 40 ++----- .../MaterialProgressBarRenderer.cs | 18 +-- .../MaterialSliderRenderer.cs | 36 ++---- .../MaterialStepperRenderer.cs | 8 +- Xamarin.Forms.Material.iOS/MaterialTextField.cs | 56 +--------- Xamarin.Forms.Material.iOS/MaterialTextManager.cs | 3 +- .../MaterialTimePickerRenderer.cs | 39 ++----- .../NoCaretMaterialTextField.cs | 18 +++ .../Properties/AssemblyInfo.cs | 22 ++-- .../ReadOnlyMaterialTextField.cs | 21 ++++ .../Xamarin.Forms.Material.iOS.csproj | 3 + .../AppCompat/PickerRenderer.cs | 8 +- .../Material/MaterialActivityIndicatorRenderer.cs | 43 +++---- .../Material/MaterialButtonRenderer.cs | 31 ++---- .../Material/MaterialColors.cs | 59 ++++++---- .../Material/MaterialContextThemeWrapper.cs | 3 +- .../Material/MaterialDatePickerRenderer.cs | 7 +- .../Material/MaterialEditorRenderer.cs | 25 ++--- .../Material/MaterialEntryRenderer.cs | 20 +--- .../Material/MaterialFormsEditText.cs | 9 +- .../Material/MaterialFormsEditTextBase.cs | 3 +- .../Material/MaterialFormsEditTextManager.cs | 7 +- .../Material/MaterialFormsTextInputLayout.cs | 2 +- .../Material/MaterialFormsTextInputLayoutBase.cs | 16 +-- .../Material/MaterialFrameRenderer.cs | 56 ++++------ .../Material/MaterialPickerEditText.cs | 26 ++--- .../Material/MaterialPickerRenderer.cs | 21 ++-- .../Material/MaterialPickerTextInputLayout.cs | 3 +- .../Material/MaterialProgressBarRenderer.cs | 60 ++++------ .../Material/MaterialSliderRenderer.cs | 79 +++++-------- .../Material/MaterialStepperRenderer.cs | 7 +- .../Material/MaterialTimePickerRenderer.cs | 7 +- .../Renderers/CircularProgress.cs | 10 +- .../Renderers/DatePickerRenderer.cs | 5 - .../Renderers/EditorRenderer.cs | 4 +- .../Resources/Layout/MaterialPickerTextInput.axml | 6 +- .../Resources/Layout/TextInputLayoutFilledBox.axml | 6 +- .../MaterialActivityIndicatorBackground.xml | 0 .../Resources/values-v21/styles.xml | 7 ++ .../Resources/values/styles.xml | 1 - .../Xamarin.Forms.Platform.Android.csproj | 9 +- Xamarin.Forms.Sandbox/App.cs | 2 +- 65 files changed, 565 insertions(+), 819 deletions(-) rename Xamarin.Forms.Controls/ControlGalleryPages/VisualGallery.xaml => Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/VisualControlsPage.xaml (99%) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/VisualControlsPage.xaml.cs create mode 100644 Xamarin.Forms.Controls/ControlGalleryPages/VisualGallery.cs delete mode 100644 Xamarin.Forms.Controls/ControlGalleryPages/VisualGallery.xaml.cs create mode 100644 Xamarin.Forms.Material.iOS/IMaterialTextField.cs create mode 100644 Xamarin.Forms.Material.iOS/NoCaretMaterialTextField.cs create mode 100644 Xamarin.Forms.Material.iOS/ReadOnlyMaterialTextField.cs rename Xamarin.Forms.Platform.Android/Resources/{drawable => drawable-v21}/MaterialActivityIndicatorBackground.xml (100%) create mode 100644 Xamarin.Forms.Platform.Android/Resources/values-v21/styles.xml diff --git a/Xamarin.Forms.ControlGallery.Android/FormsAppCompatActivity.cs b/Xamarin.Forms.ControlGallery.Android/FormsAppCompatActivity.cs index 6c12008..9737933 100644 --- a/Xamarin.Forms.ControlGallery.Android/FormsAppCompatActivity.cs +++ b/Xamarin.Forms.ControlGallery.Android/FormsAppCompatActivity.cs @@ -42,11 +42,11 @@ namespace Xamarin.Forms.ControlGallery.Android #if TEST_EXPERIMENTAL_RENDERERS // CollectionView lets us test CollectionView stuff until it's officially released - Forms.SetFlags("FastRenderers_Experimental"/*, "CollectionView_Experimental", "Visual_Experimental", "Shell_Experimental"*/); + Forms.SetFlags("FastRenderers_Experimental"/*, "CollectionView_Experimental", "Shell_Experimental"*/); #else // Fake_Flag is here so we can test for flag initialization issues // CollectionView lets us test CollectionView stuff until it's officially released - Forms.SetFlags("Fake_Flag"/*, "CollectionView_Experimental", "Visual_Experimental", "Shell_Experimental" */); + Forms.SetFlags("Fake_Flag"/*, "CollectionView_Experimental", "Shell_Experimental" */); #endif Forms.Init(this, bundle); diff --git a/Xamarin.Forms.ControlGallery.iOS/AppDelegate.cs b/Xamarin.Forms.ControlGallery.iOS/AppDelegate.cs index 4e07f28..0a17a43 100644 --- a/Xamarin.Forms.ControlGallery.iOS/AppDelegate.cs +++ b/Xamarin.Forms.ControlGallery.iOS/AppDelegate.cs @@ -159,7 +159,7 @@ namespace Xamarin.Forms.ControlGallery.iOS App.IOSVersion = int.Parse(versionPart[0]); Xamarin.Calabash.Start(); - // Forms.SetFlags("CollectionView_Experimental", "Visual_Experimental", "Shell_Experimental"); + // Forms.SetFlags("CollectionView_Experimental", "Shell_Experimental"); Forms.Init(); FormsMaps.Init(); FormsMaterial.Init(); diff --git a/Xamarin.Forms.Controls/ControlGalleryPages/VisualGallery.xaml b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/VisualControlsPage.xaml similarity index 99% rename from Xamarin.Forms.Controls/ControlGalleryPages/VisualGallery.xaml rename to Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/VisualControlsPage.xaml index 9cfa068..bf67a0e 100644 --- a/Xamarin.Forms.Controls/ControlGalleryPages/VisualGallery.xaml +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/VisualControlsPage.xaml @@ -1,7 +1,7 @@ diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/VisualControlsPage.xaml.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/VisualControlsPage.xaml.cs new file mode 100644 index 0000000..b89a888 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/VisualControlsPage.xaml.cs @@ -0,0 +1,114 @@ + +using System; +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; +#if UITEST +using NUnit.Framework; +using Xamarin.UITest; +using Xamarin.Forms.Core.UITests; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ + public partial class VisualControlsPage : ContentPage + { + bool isVisible = false; + double percentage = 0.0; + + public VisualControlsPage() + { +#if APP + InitializeComponent(); +#endif + + BindingContext = this; + } + + public double PercentageCounter + { + get { return percentage; } + set + { + percentage = value; + OnPropertyChanged(); + OnPropertyChanged(nameof(Counter)); + } + } + + public double Counter => percentage * 10; + + protected override void OnAppearing() + { + isVisible = true; + + base.OnAppearing(); + + Device.StartTimer(TimeSpan.FromSeconds(1), () => + { + var progress = PercentageCounter + 0.1; + if (progress > 1) + progress = 0; + + PercentageCounter = progress; + + return isVisible; + }); + } + + protected override void OnDisappearing() + { + isVisible = false; + + base.OnDisappearing(); + } + } + + + + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 4435, "Visual Gallery Loads", + PlatformAffected.iOS | PlatformAffected.Android)] +#if UITEST + [NUnit.Framework.Category(UITestCategories.Visual)] +#endif + public class Issue4435 : TestNavigationPage + { + const string Success = "Success"; + Label successLabel; + protected override void Init() + { + var vg = new VisualControlsPage(); + successLabel = new Label(); + vg.Appearing += Vg_Appearing; + PushAsync(new ContentPage() + { + Content = new StackLayout() + { + Children = + { + successLabel + } + } + }); + + PushAsync(vg); + } + + private void Vg_Appearing(object sender, EventArgs e) + { + Device.BeginInvokeOnMainThread(() => + { + PopAsync(); + successLabel.Text = Success; + }); + } + +#if UITEST && !__WINDOWS__ + [Test] + public void LoadingVisualGalleryPageDoesNotCrash() + { + RunningApp.WaitForElement(Success); + } +#endif + } +} diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index 89fd62c..66c0816 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -560,6 +560,10 @@ + + Code + %(Filename) + @@ -995,6 +999,10 @@ MSBuild:UpdateDesignTimeXaml + + Designer + MSBuild:UpdateDesignTimeXaml + @@ -1099,4 +1107,9 @@ MSBuild:Compile + + + VisualControlsPage.xaml + + \ No newline at end of file diff --git a/Xamarin.Forms.Controls/ControlGalleryPages/VisualGallery.cs b/Xamarin.Forms.Controls/ControlGalleryPages/VisualGallery.cs new file mode 100644 index 0000000..57f6318 --- /dev/null +++ b/Xamarin.Forms.Controls/ControlGalleryPages/VisualGallery.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Xamarin.Forms; +using Xamarin.Forms.Controls.Issues; + +namespace Xamarin.Forms.Controls +{ + public class VisualGallery : VisualControlsPage + { + public VisualGallery() + { + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls/ControlGalleryPages/VisualGallery.xaml.cs b/Xamarin.Forms.Controls/ControlGalleryPages/VisualGallery.xaml.cs deleted file mode 100644 index 7123779..0000000 --- a/Xamarin.Forms.Controls/ControlGalleryPages/VisualGallery.xaml.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; - -namespace Xamarin.Forms.Controls -{ - public partial class VisualGallery : ContentPage - { - bool isVisible = false; - double percentage = 0.0; - - public VisualGallery() - { - InitializeComponent(); - - BindingContext = this; - } - - public double PercentageCounter - { - get { return percentage; } - set - { - percentage = value; - OnPropertyChanged(); - OnPropertyChanged(nameof(Counter)); - } - } - - public double Counter => percentage * 10; - - protected override void OnAppearing() - { - isVisible = true; - - base.OnAppearing(); - - Device.StartTimer(TimeSpan.FromSeconds(1), () => - { - var progress = PercentageCounter + 0.1; - if (progress > 1) - progress = 0; - - PercentageCounter = progress; - - return isVisible; - }); - } - - protected override void OnDisappearing() - { - isVisible = false; - - base.OnDisappearing(); - } - } -} diff --git a/Xamarin.Forms.Core.UITests.Shared/UITestCategories.cs b/Xamarin.Forms.Core.UITests.Shared/UITestCategories.cs index ac0298d..78cf6ab 100644 --- a/Xamarin.Forms.Core.UITests.Shared/UITestCategories.cs +++ b/Xamarin.Forms.Core.UITests.Shared/UITestCategories.cs @@ -45,5 +45,6 @@ public const string ManualReview = "ManualReview"; public const string Performance = "Performance"; + public const string Visual = "Visual"; } } \ No newline at end of file diff --git a/Xamarin.Forms.Core.UnitTests/FlowDirectionTests.cs b/Xamarin.Forms.Core.UnitTests/FlowDirectionTests.cs index 43b3e8f..9689f02 100644 --- a/Xamarin.Forms.Core.UnitTests/FlowDirectionTests.cs +++ b/Xamarin.Forms.Core.UnitTests/FlowDirectionTests.cs @@ -532,7 +532,7 @@ namespace Xamarin.Forms.Core.UnitTests [SetUp] public override void Setup() { - Device.SetFlags(new List { ExperimentalFlags.VisualExperimental, ExperimentalFlags.ShellExperimental }); + Device.SetFlags(new List { ExperimentalFlags.ShellExperimental }); base.Setup(); Device.PlatformServices = new MockPlatformServices(); diff --git a/Xamarin.Forms.Core.UnitTests/RegistrarUnitTests.cs b/Xamarin.Forms.Core.UnitTests/RegistrarUnitTests.cs index fb820f7..e4f3745 100644 --- a/Xamarin.Forms.Core.UnitTests/RegistrarUnitTests.cs +++ b/Xamarin.Forms.Core.UnitTests/RegistrarUnitTests.cs @@ -46,7 +46,6 @@ namespace Xamarin.Forms.Core.UnitTests public override void Setup() { base.Setup(); - Device.SetFlags(new List { ExperimentalFlags.VisualExperimental }); Device.PlatformServices = new MockPlatformServices(); Internals.Registrar.RegisterAll(new[] { typeof (TestHandlerAttribute) diff --git a/Xamarin.Forms.Core.UnitTests/VisualTests.cs b/Xamarin.Forms.Core.UnitTests/VisualTests.cs index 9fa03da..da13ccd 100644 --- a/Xamarin.Forms.Core.UnitTests/VisualTests.cs +++ b/Xamarin.Forms.Core.UnitTests/VisualTests.cs @@ -12,7 +12,7 @@ namespace Xamarin.Forms.Core.UnitTests [SetUp] public override void Setup() { - Device.SetFlags(new List { ExperimentalFlags.VisualExperimental, ExperimentalFlags.ShellExperimental }); + Device.SetFlags(new List { ExperimentalFlags.ShellExperimental }); base.Setup(); var mockDeviceInfo = new TestDeviceInfo(); Device.Info = mockDeviceInfo; diff --git a/Xamarin.Forms.Core/ExperimentalFlags.cs b/Xamarin.Forms.Core/ExperimentalFlags.cs index 23a5e35..5940903 100644 --- a/Xamarin.Forms.Core/ExperimentalFlags.cs +++ b/Xamarin.Forms.Core/ExperimentalFlags.cs @@ -10,7 +10,6 @@ namespace Xamarin.Forms internal static class ExperimentalFlags { internal const string CollectionViewExperimental = "CollectionView_Experimental"; - internal const string VisualExperimental = "Visual_Experimental"; internal const string ShellExperimental = "Shell_Experimental"; [EditorBrowsable(EditorBrowsableState.Never)] diff --git a/Xamarin.Forms.Core/Registrar.cs b/Xamarin.Forms.Core/Registrar.cs index cdb5188..a164cea 100644 --- a/Xamarin.Forms.Core/Registrar.cs +++ b/Xamarin.Forms.Core/Registrar.cs @@ -153,9 +153,6 @@ namespace Xamarin.Forms.Internals bool LookupHandlerType(Type viewType, Type visualType, out Type handlerType) { - if (_defaultVisualType != visualType) - VisualElement.VerifyVisualFlagEnabled(); - visualType = visualType ?? _defaultVisualType; while (viewType != null && viewType != typeof(Element)) { diff --git a/Xamarin.Forms.Core/VisualElement.cs b/Xamarin.Forms.Core/VisualElement.cs index 30e5f8f..cc9a739 100644 --- a/Xamarin.Forms.Core/VisualElement.cs +++ b/Xamarin.Forms.Core/VisualElement.cs @@ -927,9 +927,6 @@ namespace Xamarin.Forms static void OnVisualChanged(BindableObject bindable, object oldValue, object newValue) { - if(newValue != Xamarin.Forms.VisualMarker.Default) - VerifyVisualFlagEnabled(); - var self = bindable as IVisualController; var newVisual = (IVisual)newValue; @@ -1065,13 +1062,5 @@ namespace Xamarin.Forms } } - - [EditorBrowsable(EditorBrowsableState.Never)] - public static void VerifyVisualFlagEnabled( - string constructorHint = null, - [CallerMemberName] string memberName = "") - { - ExperimentalFlags.VerifyFlagEnabled(nameof(Visual), ExperimentalFlags.VisualExperimental); - } } } diff --git a/Xamarin.Forms.Material.iOS/IMaterialEntryRenderer.cs b/Xamarin.Forms.Material.iOS/IMaterialEntryRenderer.cs index 168d8a4..a883fb0 100644 --- a/Xamarin.Forms.Material.iOS/IMaterialEntryRenderer.cs +++ b/Xamarin.Forms.Material.iOS/IMaterialEntryRenderer.cs @@ -6,7 +6,7 @@ using System.Text; using Foundation; using UIKit; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public interface IMaterialEntryRenderer { diff --git a/Xamarin.Forms.Material.iOS/IMaterialTextField.cs b/Xamarin.Forms.Material.iOS/IMaterialTextField.cs new file mode 100644 index 0000000..8a9c4e7 --- /dev/null +++ b/Xamarin.Forms.Material.iOS/IMaterialTextField.cs @@ -0,0 +1,13 @@ +using MaterialComponents; +using MTextInputControllerBase = MaterialComponents.TextInputControllerBase; + +namespace Xamarin.Forms.Material.iOS +{ + internal interface IMaterialTextField + { + SemanticColorScheme ColorScheme { get; set; } + TypographyScheme TypographyScheme { get; set; } + MTextInputControllerBase ActiveTextInputController { get; set; } + ITextInput TextInput { get; } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Material.iOS/MaterialActivityIndicatorRenderer.cs b/Xamarin.Forms.Material.iOS/MaterialActivityIndicatorRenderer.cs index e3af54f..5ee17ea 100644 --- a/Xamarin.Forms.Material.iOS/MaterialActivityIndicatorRenderer.cs +++ b/Xamarin.Forms.Material.iOS/MaterialActivityIndicatorRenderer.cs @@ -4,11 +4,11 @@ using CoreAnimation; using CoreGraphics; using MaterialComponents; using UIKit; -using Xamarin.Forms; +using Xamarin.Forms.Platform.iOS; using MActivityIndicator = MaterialComponents.ActivityIndicator; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public class MaterialActivityIndicatorRenderer : ViewRenderer { @@ -18,17 +18,10 @@ namespace Xamarin.Forms.Platform.iOS.Material const float _defaultRadius = 22; const float _defaultStrokeWidth = 4; const float _defaultSize = 2 * _defaultRadius + _defaultStrokeWidth; - SemanticColorScheme _defaultColorScheme; SemanticColorScheme _colorScheme; - CAShapeLayer _backgroundLayer; - public MaterialActivityIndicatorRenderer() - { - VisualElement.VerifyVisualFlagEnabled(); - } - protected override void OnElementChanged(ElementChangedEventArgs e) { _colorScheme?.Dispose(); @@ -137,10 +130,7 @@ namespace Xamarin.Forms.Platform.iOS.Material _backgroundLayer.StrokeColor = color.ToCGColor(); } - void UpdateColor() - { - _colorScheme.PrimaryColor = Element.Color.IsDefault ? _defaultColorScheme.PrimaryColor : Element.Color.ToUIColor(); - } + void UpdateColor() => _colorScheme.PrimaryColor = Element.Color.IsDefault ? _defaultColorScheme.PrimaryColor : Element.Color.ToUIColor(); void UpdateIsRunning() { diff --git a/Xamarin.Forms.Material.iOS/MaterialButtonRenderer.cs b/Xamarin.Forms.Material.iOS/MaterialButtonRenderer.cs index 414f589..eda3e9b 100644 --- a/Xamarin.Forms.Material.iOS/MaterialButtonRenderer.cs +++ b/Xamarin.Forms.Material.iOS/MaterialButtonRenderer.cs @@ -1,33 +1,24 @@ using System; using System.ComponentModel; -using System.Diagnostics; using CoreGraphics; -using Foundation; using MaterialComponents; using UIKit; -using Xamarin.Forms; -using Xamarin.Forms.PlatformConfiguration.iOSSpecific; -using Specifics = Xamarin.Forms.PlatformConfiguration.iOSSpecific; +using Xamarin.Forms.Platform.iOS; using MButton = MaterialComponents.Button; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public class MaterialButtonRenderer : ViewRenderer, IImageVisualElementRenderer, IButtonLayoutRenderer { bool _isDisposed; - UIColor _defaultBorderColor; nfloat _defaultBorderWidth = -1; - ButtonScheme _defaultButtonScheme; ButtonScheme _buttonScheme; - ButtonLayoutManager _buttonLayoutManager; public MaterialButtonRenderer() { - VisualElement.VerifyVisualFlagEnabled(); - _buttonLayoutManager = new ButtonLayoutManager(this, preserveInitialPadding: true, spacingAdjustsPadding: false, @@ -84,7 +75,6 @@ namespace Xamarin.Forms.Platform.iOS.Material UpdateBorder(); UpdateTextColor(); _buttonLayoutManager?.Update(); - ApplyTheme(); } } @@ -99,15 +89,8 @@ namespace Xamarin.Forms.Platform.iOS.Material }; } - protected virtual void ApplyTheme() - { - ContainedButtonThemer.ApplyScheme(_buttonScheme, Control); - } - - protected override MButton CreateNativeControl() - { - return new MButton(); - } + protected virtual void ApplyTheme() => ContainedButtonThemer.ApplyScheme(_buttonScheme, Control); + protected override MButton CreateNativeControl() => new MButton(); protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { @@ -159,10 +142,7 @@ namespace Xamarin.Forms.Platform.iOS.Material Element?.SendClicked(); } - void OnButtonTouchDown(object sender, EventArgs eventArgs) - { - Element?.SendPressed(); - } + void OnButtonTouchDown(object sender, EventArgs eventArgs) => Element?.SendPressed(); protected override void SetBackgroundColor(Color color) { @@ -187,9 +167,6 @@ namespace Xamarin.Forms.Platform.iOS.Material { // NOTE: borders are not a "supported" style of the contained // button, thus we don't use the themer here. - - // BorderColor - Color borderColor = Element.BorderColor; if (_defaultBorderColor == null) @@ -200,8 +177,6 @@ namespace Xamarin.Forms.Platform.iOS.Material else Control.SetBorderColor(borderColor.ToUIColor(), UIControlState.Normal); - // BorderWidth - double borderWidth = Element.BorderWidth; if (_defaultBorderWidth == -1) @@ -263,19 +238,13 @@ namespace Xamarin.Forms.Platform.iOS.Material } // IImageVisualElementRenderer - bool IImageVisualElementRenderer.IsDisposed => _isDisposed; - void IImageVisualElementRenderer.SetImage(UIImage image) => _buttonLayoutManager.SetImage(image); - UIImageView IImageVisualElementRenderer.GetImage() => Control?.ImageView; // IButtonLayoutRenderer - UIButton IButtonLayoutRenderer.Control => Control; - IImageVisualElementRenderer IButtonLayoutRenderer.ImageVisualElementRenderer => this; - nfloat IButtonLayoutRenderer.MinimumHeight => _buttonScheme?.MinimumHeight ?? -1; } } diff --git a/Xamarin.Forms.Material.iOS/MaterialDatePickerRenderer.cs b/Xamarin.Forms.Material.iOS/MaterialDatePickerRenderer.cs index 8664295..797fe4b 100644 --- a/Xamarin.Forms.Material.iOS/MaterialDatePickerRenderer.cs +++ b/Xamarin.Forms.Material.iOS/MaterialDatePickerRenderer.cs @@ -1,48 +1,21 @@ using System.ComponentModel; using UIKit; +using Xamarin.Forms.Platform.iOS; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public class MaterialDatePickerRenderer : DatePickerRendererBase, IMaterialEntryRenderer { - public MaterialDatePickerRenderer() - { - VisualElement.VerifyVisualFlagEnabled(); - } - - protected override MaterialTextField CreateNativeControl() - { - var field = new NoCaretMaterialTextField(this, Element); - return field; - } - - protected override void SetBackgroundColor(Color color) - { - ApplyTheme(); - } + protected override MaterialTextField CreateNativeControl() => new NoCaretMaterialTextField(this, Element); + protected override void SetBackgroundColor(Color color) => ApplyTheme(); + protected internal override void UpdateTextColor() => Control?.UpdateTextColor(this); + protected virtual void ApplyTheme() => Control?.ApplyTheme(this); protected internal override void UpdateFont() { base.UpdateFont(); Control?.ApplyTypographyScheme(Element); } - - - protected internal override void UpdateTextColor() - { - Control?.UpdateTextColor(this); - } - - - protected virtual void ApplyTheme() - { - Control?.ApplyTheme(this); - } - - internal void UpdatePlaceholder() - { - Control?.UpdatePlaceholder(this); - } protected override void OnElementChanged(ElementChangedEventArgs e) { @@ -50,9 +23,9 @@ namespace Xamarin.Forms.Platform.iOS.Material UpdatePlaceholder(); } + void UpdatePlaceholder() => Control?.UpdatePlaceholder(this); string IMaterialEntryRenderer.Placeholder => string.Empty; Color IMaterialEntryRenderer.PlaceholderColor => Color.Default; - Color IMaterialEntryRenderer.TextColor => Element?.TextColor ?? Color.Default; Color IMaterialEntryRenderer.BackgroundColor => Element?.BackgroundColor ?? Color.Default; } diff --git a/Xamarin.Forms.Material.iOS/MaterialEditorRenderer.cs b/Xamarin.Forms.Material.iOS/MaterialEditorRenderer.cs index ba580ff..283f96b 100644 --- a/Xamarin.Forms.Material.iOS/MaterialEditorRenderer.cs +++ b/Xamarin.Forms.Material.iOS/MaterialEditorRenderer.cs @@ -1,34 +1,21 @@ using UIKit; using MaterialComponents; using System; +using Xamarin.Forms.Platform.iOS; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public class MaterialEditorRenderer : EditorRendererBase, IMaterialEntryRenderer { bool _hackHasRan = false; - protected override MaterialMultilineTextField CreateNativeControl() - { - return new MaterialMultilineTextField(this, Element); - } - - protected override void SetBackgroundColor(Color color) - { - ApplyTheme(); - } - - - protected internal override void UpdateTextColor() - { - Control?.UpdateTextColor(this); - } - + protected override MaterialMultilineTextField CreateNativeControl() => new MaterialMultilineTextField(this, Element); + protected IntrinsicHeightTextView IntrinsicHeightTextView => (IntrinsicHeightTextView)TextView; + protected override UITextView TextView => Control?.TextView; + protected override void SetBackgroundColor(Color color) => ApplyTheme(); - protected virtual void ApplyTheme() - { - Control?.ApplyTheme(this); - } + protected internal override void UpdateTextColor() => Control?.UpdateTextColor(this); + protected virtual void ApplyTheme() => Control?.ApplyTheme(this); protected internal override void UpdateFont() { @@ -99,17 +86,9 @@ namespace Xamarin.Forms.Platform.iOS.Material }); } - - // Placeholder is currently broken upstream and doesn't animate to the correct scale string IMaterialEntryRenderer.Placeholder => Element?.Placeholder; - // string IMaterialEntryRenderer.Placeholder => String.Empty; - Color IMaterialEntryRenderer.TextColor => Element?.TextColor ?? Color.Default; Color IMaterialEntryRenderer.PlaceholderColor => Element?.PlaceholderColor ?? Color.Default; Color IMaterialEntryRenderer.BackgroundColor => Element?.BackgroundColor ?? Color.Default; - - protected IntrinsicHeightTextView IntrinsicHeightTextView => (IntrinsicHeightTextView)TextView; - protected override UITextView TextView => Control?.TextView; - } } \ No newline at end of file diff --git a/Xamarin.Forms.Material.iOS/MaterialEntryRenderer.cs b/Xamarin.Forms.Material.iOS/MaterialEntryRenderer.cs index e3bf4be..367701c 100644 --- a/Xamarin.Forms.Material.iOS/MaterialEntryRenderer.cs +++ b/Xamarin.Forms.Material.iOS/MaterialEntryRenderer.cs @@ -1,26 +1,16 @@ using CoreGraphics; using UIKit; +using Xamarin.Forms.Platform.iOS; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public class MaterialEntryRenderer : EntryRendererBase, IMaterialEntryRenderer { - - public MaterialEntryRenderer() - { - VisualElement.VerifyVisualFlagEnabled(); - } - - protected override MaterialTextField CreateNativeControl() - { - var field = new MaterialTextField(this, Element); - return field; - } - - protected override void SetBackgroundColor(Color color) - { - ApplyTheme(); - } + protected override MaterialTextField CreateNativeControl() => new MaterialTextField(this, Element); + protected override void SetBackgroundColor(Color color) => ApplyTheme(); + protected internal override void UpdateColor() => Control?.UpdateTextColor(this); + protected virtual void ApplyTheme() => Control?.ApplyTheme(this); + protected internal override void UpdatePlaceholder() => Control?.UpdatePlaceholder(this); protected internal override void UpdateFont() { @@ -28,24 +18,6 @@ namespace Xamarin.Forms.Platform.iOS.Material Control?.ApplyTypographyScheme(Element); } - - protected internal override void UpdateColor() - { - Control?.UpdateTextColor(this); - } - - - protected virtual void ApplyTheme() - { - Control?.ApplyTheme(this); - } - - protected internal override void UpdatePlaceholder() - { - Control?.UpdatePlaceholder(this); - - } - Color IMaterialEntryRenderer.TextColor => Element?.TextColor ?? Color.Default; Color IMaterialEntryRenderer.PlaceholderColor => Element?.PlaceholderColor ?? Color.Default; Color IMaterialEntryRenderer.BackgroundColor => Element?.BackgroundColor ?? Color.Default; diff --git a/Xamarin.Forms.Material.iOS/MaterialFrameRenderer.cs b/Xamarin.Forms.Material.iOS/MaterialFrameRenderer.cs index 846e8c4..e41ab26 100644 --- a/Xamarin.Forms.Material.iOS/MaterialFrameRenderer.cs +++ b/Xamarin.Forms.Material.iOS/MaterialFrameRenderer.cs @@ -5,56 +5,28 @@ using CoreGraphics; using MaterialComponents; using UIKit; using Xamarin.Forms; +using Xamarin.Forms.Platform.iOS; using MCard = MaterialComponents.Card; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public class MaterialFrameRenderer : MCard, IVisualElementRenderer { CardScheme _defaultCardScheme; CardScheme _cardScheme; - nfloat _defaultCornerRadius = -1f; - VisualElementPackager _packager; VisualElementTracker _tracker; bool _disposed = false; public event EventHandler ElementChanged; - - public MaterialFrameRenderer() - { - VisualElement.VerifyVisualFlagEnabled(); - } - public Frame Element { get; private set; } - - protected override void Dispose(bool disposing) - { - if (disposing && !_disposed) - { - _disposed = true; - if (_packager == null) - return; - - SetElement(null); - - _packager.Dispose(); - _packager = null; - - _tracker.NativeControlUpdated -= OnNativeControlUpdated; - _tracker.Dispose(); - _tracker = null; - } - - base.Dispose(disposing); - } - + public override void WillRemoveSubview(UIView uiview) { var content = Element?.Content; - if (content != null && uiview == Platform.GetRenderer(content)) + if (content != null && uiview == Platform.iOS.Platform.GetRenderer(content)) { uiview.Layer.Mask = null; } @@ -70,7 +42,7 @@ namespace Xamarin.Forms.Platform.iOS.Material var content = Element?.Content; if (content != null && Layer is ShapedShadowLayer shadowLayer && shadowLayer.ShapeLayer.Path is CGPath shapePath) { - var renderer = Platform.GetRenderer(content); + var renderer = Platform.iOS.Platform.GetRenderer(content); if (renderer is UIView uiview) { var padding = Element.Padding; @@ -83,30 +55,6 @@ namespace Xamarin.Forms.Platform.iOS.Material } } - protected virtual CardScheme CreateCardScheme() - { - return new CardScheme - { - ColorScheme = MaterialColors.Light.CreateColorScheme(), - ShapeScheme = new ShapeScheme(), - }; - } - - protected virtual void ApplyTheme() - { - if (Element.BorderColor.IsDefault) - CardThemer.ApplyScheme(_cardScheme, this); - else - CardThemer.ApplyOutlinedVariant(_cardScheme, this); - - // a special case for no shadow - if (!Element.HasShadow) - SetShadowElevation(0, UIControlState.Normal); - - // this is set in the theme, so we must always disable it - Interactable = false; - } - public void SetElement(VisualElement element) { _cardScheme?.Dispose(); @@ -134,7 +82,6 @@ namespace Xamarin.Forms.Platform.iOS.Material _packager.Load(); _tracker = new VisualElementTracker(this); - _tracker.NativeControlUpdated += OnNativeControlUpdated; } Element.PropertyChanged += OnElementPropertyChanged; @@ -142,13 +89,56 @@ namespace Xamarin.Forms.Platform.iOS.Material UpdateCornerRadius(); UpdateBorderColor(); UpdateBackgroundColor(); - ApplyTheme(); } OnElementChanged(new VisualElementChangedEventArgs(oldElement, element)); } + protected override void Dispose(bool disposing) + { + if (disposing && !_disposed) + { + _disposed = true; + if (_packager == null) + return; + + SetElement(null); + + _packager.Dispose(); + _packager = null; + + _tracker.Dispose(); + _tracker = null; + } + + base.Dispose(disposing); + } + + protected virtual CardScheme CreateCardScheme() + { + return new CardScheme + { + ColorScheme = MaterialColors.Light.CreateColorScheme(), + ShapeScheme = new ShapeScheme(), + }; + } + + protected virtual void ApplyTheme() + { + if (Element.BorderColor.IsDefault) + CardThemer.ApplyScheme(_cardScheme, this); + else + CardThemer.ApplyOutlinedVariant(_cardScheme, this); + + // a special case for no shadow + if (!Element.HasShadow) + SetShadowElevation(0, UIControlState.Normal); + + // this is set in the theme, so we must always disable it + Interactable = false; + } + protected virtual void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { var updatedTheme = false; @@ -177,14 +167,7 @@ namespace Xamarin.Forms.Platform.iOS.Material ApplyTheme(); } - protected virtual void OnElementChanged(VisualElementChangedEventArgs e) - { - ElementChanged?.Invoke(this, e); - } - - void OnNativeControlUpdated(object sender, EventArgs eventArgs) - { - } + protected virtual void OnElementChanged(VisualElementChangedEventArgs e) => ElementChanged?.Invoke(this, e); void UpdateCornerRadius() { @@ -224,19 +207,13 @@ namespace Xamarin.Forms.Platform.iOS.Material } // IVisualElementRenderer - VisualElement IVisualElementRenderer.Element => Element; - UIView IVisualElementRenderer.NativeView => this; - UIViewController IVisualElementRenderer.ViewController => null; - SizeRequest IVisualElementRenderer.GetDesiredSize(double widthConstraint, double heightConstraint) => this.GetSizeRequest(widthConstraint, heightConstraint, 44, 44); - void IVisualElementRenderer.SetElement(VisualElement element) => SetElement(element); - void IVisualElementRenderer.SetElementSize(Size size) => Layout.LayoutChildIntoBoundingRegion(Element, new Rectangle(Element.X, Element.Y, size.Width, size.Height)); } diff --git a/Xamarin.Forms.Material.iOS/MaterialMultiLineTextField.cs b/Xamarin.Forms.Material.iOS/MaterialMultiLineTextField.cs index e3cd673..836d710 100644 --- a/Xamarin.Forms.Material.iOS/MaterialMultiLineTextField.cs +++ b/Xamarin.Forms.Material.iOS/MaterialMultiLineTextField.cs @@ -6,22 +6,27 @@ using MMultilineTextField = MaterialComponents.MultilineTextField; using MTextInputControllerBase = MaterialComponents.TextInputControllerBase; using Xamarin.Forms.Internals; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public class MaterialMultilineTextField : MMultilineTextField, IMaterialTextField { + CGSize _contentSize; + + public MaterialMultilineTextField(IMaterialEntryRenderer element, IFontElement fontElement) => MaterialTextManager.Init(element, this, fontElement); + public SemanticColorScheme ColorScheme { get; set; } public TypographyScheme TypographyScheme { get; set; } public MTextInputControllerBase ActiveTextInputController { get; set; } public ITextInput TextInput => this; - internal bool AutoSizeWithChanges { get; set; } = false; - CGSize _contentSize; - - public MaterialMultilineTextField(IMaterialEntryRenderer element, IFontElement fontElement) + public override CGRect Frame { - VisualElement.VerifyVisualFlagEnabled(); - MaterialTextManager.Init(element, this, fontElement); + get => base.Frame; + set + { + base.Frame = value; + UpdateIfTextViewShouldStopExpanding(); + } } public override CGSize SizeThatFits(CGSize size) @@ -75,16 +80,6 @@ namespace Xamarin.Forms.Platform.iOS.Material } } - public override CGRect Frame - { - get => base.Frame; - set - { - base.Frame = value; - UpdateIfTextViewShouldStopExpanding(); - } - } - int NumberOfLines { get @@ -96,14 +91,10 @@ namespace Xamarin.Forms.Platform.iOS.Material } } + internal bool AutoSizeWithChanges { get; set; } = false; internal void ApplyTypographyScheme(IFontElement fontElement) => MaterialTextManager.ApplyTypographyScheme(this, fontElement); - internal void ApplyTheme(IMaterialEntryRenderer element) => MaterialTextManager.ApplyTheme(this, element); - internal void UpdatePlaceholder(IMaterialEntryRenderer element) => MaterialTextManager.UpdatePlaceholder(this, element); - internal void UpdateTextColor(IMaterialEntryRenderer element) => MaterialTextManager.UpdateTextColor(this, element); - - } } diff --git a/Xamarin.Forms.Material.iOS/MaterialPickerRenderer.cs b/Xamarin.Forms.Material.iOS/MaterialPickerRenderer.cs index d80db95..a969842 100644 --- a/Xamarin.Forms.Material.iOS/MaterialPickerRenderer.cs +++ b/Xamarin.Forms.Material.iOS/MaterialPickerRenderer.cs @@ -1,48 +1,23 @@ using System.ComponentModel; using UIKit; +using Xamarin.Forms.Platform.iOS; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public class MaterialPickerRenderer : PickerRendererBase, IMaterialEntryRenderer { - public MaterialPickerRenderer() - { - VisualElement.VerifyVisualFlagEnabled(); - } - - protected override MaterialTextField CreateNativeControl() - { - var field = new ReadOnlyMaterialTextField(this, Element); - return field; - } - - protected override void SetBackgroundColor(Color color) - { - ApplyTheme(); - } + protected override MaterialTextField CreateNativeControl() => new ReadOnlyMaterialTextField(this, Element); + protected override void SetBackgroundColor(Color color) => ApplyTheme(); protected internal override void UpdateFont() { base.UpdateFont(); Control?.ApplyTypographyScheme(Element); } - - protected internal override void UpdateTextColor() - { - Control?.UpdateTextColor(this); - } - - - protected virtual void ApplyTheme() - { - Control?.ApplyTheme(this); - } - - protected internal override void UpdatePlaceholder() - { - Control?.UpdatePlaceholder(this); - } + protected internal override void UpdateTextColor() => Control?.UpdateTextColor(this); + protected virtual void ApplyTheme() => Control?.ApplyTheme(this); + protected internal override void UpdatePlaceholder() => Control?.UpdatePlaceholder(this); protected override void OnElementChanged(ElementChangedEventArgs e) { @@ -54,6 +29,5 @@ namespace Xamarin.Forms.Platform.iOS.Material Color IMaterialEntryRenderer.PlaceholderColor => Color.Default; Color IMaterialEntryRenderer.TextColor => Element?.TextColor ?? Color.Default; Color IMaterialEntryRenderer.BackgroundColor => Element?.BackgroundColor ?? Color.Default; - } } \ No newline at end of file diff --git a/Xamarin.Forms.Material.iOS/MaterialProgressBarRenderer.cs b/Xamarin.Forms.Material.iOS/MaterialProgressBarRenderer.cs index 883e84f..ba55a3a 100644 --- a/Xamarin.Forms.Material.iOS/MaterialProgressBarRenderer.cs +++ b/Xamarin.Forms.Material.iOS/MaterialProgressBarRenderer.cs @@ -4,20 +4,16 @@ using CoreGraphics; using MaterialComponents; using UIKit; using Xamarin.Forms; +using Xamarin.Forms.Platform.iOS; using MProgressView = MaterialComponents.ProgressView; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public class MaterialProgressBarRenderer : ViewRenderer { BasicColorScheme _defaultColorScheme; BasicColorScheme _colorScheme; - public MaterialProgressBarRenderer() - { - VisualElement.VerifyVisualFlagEnabled(); - } - protected override void OnElementChanged(ElementChangedEventArgs e) { _colorScheme?.Dispose(); @@ -62,10 +58,7 @@ namespace Xamarin.Forms.Platform.iOS.Material #pragma warning restore CS0618 // Type or member is obsolete } - protected override MProgressView CreateNativeControl() - { - return new MProgressView(); - } + protected override MProgressView CreateNativeControl() => new MProgressView(); public override CGSize SizeThatFits(CGSize size) { @@ -114,10 +107,7 @@ namespace Xamarin.Forms.Platform.iOS.Material ApplyTheme(); } - void UpdateProgressColor() - { - UpdateAllColors(); - } + void UpdateProgressColor() => UpdateAllColors(); void UpdateAllColors() { diff --git a/Xamarin.Forms.Material.iOS/MaterialSliderRenderer.cs b/Xamarin.Forms.Material.iOS/MaterialSliderRenderer.cs index 5d5fa2b..fe54692 100644 --- a/Xamarin.Forms.Material.iOS/MaterialSliderRenderer.cs +++ b/Xamarin.Forms.Material.iOS/MaterialSliderRenderer.cs @@ -4,20 +4,15 @@ using CoreGraphics; using MaterialComponents; using UIKit; using Xamarin.Forms; +using Xamarin.Forms.Platform.iOS; using MSlider = MaterialComponents.Slider; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public class MaterialSliderRenderer : ViewRenderer { SemanticColorScheme _defaultColorScheme; SemanticColorScheme _colorScheme; - - public MaterialSliderRenderer() - { - VisualElement.VerifyVisualFlagEnabled(); - } - protected override void Dispose(bool disposing) { if (Control != null) @@ -56,11 +51,6 @@ namespace Xamarin.Forms.Platform.iOS.Material } } - protected virtual SemanticColorScheme CreateColorScheme() - { - return MaterialColors.Light.CreateColorScheme(); - } - protected virtual void ApplyTheme() { SliderColorThemer.ApplySemanticColorScheme(CreateColorScheme(), Control); @@ -72,10 +62,6 @@ namespace Xamarin.Forms.Platform.iOS.Material OverrideThemeColors(); } - protected override MSlider CreateNativeControl() - { - return new MSlider { StatefulApiEnabled = true }; - } public override CGSize SizeThatFits(CGSize size) { @@ -114,15 +100,12 @@ namespace Xamarin.Forms.Platform.iOS.Material ApplyTheme(); } - void UpdateMaximum() - { - Control.MaximumValue = (nfloat)Element.Maximum; - } + protected override MSlider CreateNativeControl() => new MSlider { StatefulApiEnabled = true }; + protected virtual SemanticColorScheme CreateColorScheme() => MaterialColors.Light.CreateColorScheme(); - void UpdateMinimum() - { - Control.MinimumValue = (nfloat)Element.Minimum; - } + void UpdateMaximum() => Control.MaximumValue = (nfloat)Element.Maximum; + void UpdateMinimum() => Control.MinimumValue = (nfloat)Element.Minimum; + void OnControlValueChanged(object sender, EventArgs eventArgs) => Element.SetValueFromRenderer(Slider.ValueProperty, Control.Value); void UpdateValue() { @@ -162,10 +145,5 @@ namespace Xamarin.Forms.Platform.iOS.Material if (!thumbColor.IsDefault) Control.SetThumbColor(thumbColor.ToUIColor(), UIControlState.Normal); } - - void OnControlValueChanged(object sender, EventArgs eventArgs) - { - Element.SetValueFromRenderer(Slider.ValueProperty, Control.Value); - } } } \ No newline at end of file diff --git a/Xamarin.Forms.Material.iOS/MaterialStepperRenderer.cs b/Xamarin.Forms.Material.iOS/MaterialStepperRenderer.cs index e3e9c55..1ce3992 100644 --- a/Xamarin.Forms.Material.iOS/MaterialStepperRenderer.cs +++ b/Xamarin.Forms.Material.iOS/MaterialStepperRenderer.cs @@ -3,19 +3,15 @@ using System.ComponentModel; using CoreGraphics; using MaterialComponents; using UIKit; +using Xamarin.Forms.Platform.iOS; using MButton = MaterialComponents.Button; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public class MaterialStepperRenderer : ViewRenderer { ButtonScheme _buttonScheme; - public MaterialStepperRenderer() - { - VisualElement.VerifyVisualFlagEnabled(); - } - protected override void Dispose(bool disposing) { if (Control is MaterialStepper control) diff --git a/Xamarin.Forms.Material.iOS/MaterialTextField.cs b/Xamarin.Forms.Material.iOS/MaterialTextField.cs index ac73d4e..b9b587d 100644 --- a/Xamarin.Forms.Material.iOS/MaterialTextField.cs +++ b/Xamarin.Forms.Material.iOS/MaterialTextField.cs @@ -5,35 +5,17 @@ using UIKit; using MTextField = MaterialComponents.TextField; using MTextInputControllerFilled = MaterialComponents.TextInputControllerFilled; using MTextInputControllerBase = MaterialComponents.TextInputControllerBase; -using System.Collections.Generic; -using ObjCRuntime; -using Foundation; using Xamarin.Forms.Internals; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { - internal interface IMaterialTextField - { - SemanticColorScheme ColorScheme { get; set; } - TypographyScheme TypographyScheme { get; set; } - MTextInputControllerBase ActiveTextInputController { get; set; } - - ITextInput TextInput { get; } - } - public class MaterialTextField : MTextField, IMaterialTextField { public SemanticColorScheme ColorScheme { get; set; } public TypographyScheme TypographyScheme { get; set; } public MTextInputControllerBase ActiveTextInputController { get; set; } - public ITextInput TextInput => this; - - public MaterialTextField(IMaterialEntryRenderer element, IFontElement fontElement) - { - VisualElement.VerifyVisualFlagEnabled(); - MaterialTextManager.Init(element, this, fontElement); - } + public MaterialTextField(IMaterialEntryRenderer element, IFontElement fontElement) => MaterialTextManager.Init(element, this, fontElement); public override CGSize SizeThatFits(CGSize size) { @@ -47,42 +29,8 @@ namespace Xamarin.Forms.Platform.iOS.Material internal void ApplyTypographyScheme(IFontElement fontElement) => MaterialTextManager.ApplyTypographyScheme(this, fontElement); - internal void ApplyTheme(IMaterialEntryRenderer element) => MaterialTextManager.ApplyTheme(this, element); - internal void UpdatePlaceholder(IMaterialEntryRenderer element) => MaterialTextManager.UpdatePlaceholder(this, element); - - internal void UpdateTextColor(IMaterialEntryRenderer element) => MaterialTextManager.UpdateTextColor(this, element); } - - - internal class NoCaretMaterialTextField : MaterialTextField - { - public NoCaretMaterialTextField(IMaterialEntryRenderer element, IFontElement fontElement) : base(element, fontElement) - { - SpellCheckingType = UITextSpellCheckingType.No; - AutocorrectionType = UITextAutocorrectionType.No; - AutocapitalizationType = UITextAutocapitalizationType.None; - } - - public override CGRect GetCaretRectForPosition(UITextPosition position) - { - return new CGRect(); - } - } - - internal class ReadOnlyMaterialTextField : NoCaretMaterialTextField - { - readonly HashSet enableActions; - - public ReadOnlyMaterialTextField(IMaterialEntryRenderer element, IFontElement fontElement) : base(element, fontElement) - { - string[] actions = { "copy:", "select:", "selectAll:" }; - enableActions = new HashSet(actions); - } - - public override bool CanPerform(Selector action, NSObject withSender) - => enableActions.Contains(action.Name); - } } \ No newline at end of file diff --git a/Xamarin.Forms.Material.iOS/MaterialTextManager.cs b/Xamarin.Forms.Material.iOS/MaterialTextManager.cs index e9eb20b..7292cde 100644 --- a/Xamarin.Forms.Material.iOS/MaterialTextManager.cs +++ b/Xamarin.Forms.Material.iOS/MaterialTextManager.cs @@ -9,8 +9,9 @@ using System.Collections.Generic; using ObjCRuntime; using Foundation; using Xamarin.Forms.Internals; +using Xamarin.Forms.Platform.iOS; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { internal static class MaterialTextManager { diff --git a/Xamarin.Forms.Material.iOS/MaterialTimePickerRenderer.cs b/Xamarin.Forms.Material.iOS/MaterialTimePickerRenderer.cs index 5487d14..0282196 100644 --- a/Xamarin.Forms.Material.iOS/MaterialTimePickerRenderer.cs +++ b/Xamarin.Forms.Material.iOS/MaterialTimePickerRenderer.cs @@ -1,25 +1,12 @@ using System.ComponentModel; using UIKit; +using Xamarin.Forms.Platform.iOS; -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS { public class MaterialTimePickerRenderer : TimePickerRendererBase, IMaterialEntryRenderer { - public MaterialTimePickerRenderer() - { - VisualElement.VerifyVisualFlagEnabled(); - } - - protected override MaterialTextField CreateNativeControl() - { - var field = new NoCaretMaterialTextField(this, Element); - return field; - } - - protected override void SetBackgroundColor(Color color) - { - ApplyTheme(); - } + internal void UpdatePlaceholder() => Control?.UpdatePlaceholder(this); protected internal override void UpdateFont() { @@ -27,21 +14,10 @@ namespace Xamarin.Forms.Platform.iOS.Material Control?.ApplyTypographyScheme(Element); } - protected internal override void UpdateTextColor() - { - Control?.UpdateTextColor(this); - } - - - protected virtual void ApplyTheme() - { - Control?.ApplyTheme(this); - } - - internal void UpdatePlaceholder() - { - Control?.UpdatePlaceholder(this); - } + protected override MaterialTextField CreateNativeControl() => new NoCaretMaterialTextField(this, Element); + protected override void SetBackgroundColor(Color color) => ApplyTheme(); + protected internal override void UpdateTextColor() => Control?.UpdateTextColor(this); + protected virtual void ApplyTheme() => Control?.ApplyTheme(this); protected override void OnElementChanged(ElementChangedEventArgs e) { @@ -51,7 +27,6 @@ namespace Xamarin.Forms.Platform.iOS.Material string IMaterialEntryRenderer.Placeholder => string.Empty; Color IMaterialEntryRenderer.PlaceholderColor => Color.Default; - Color IMaterialEntryRenderer.TextColor => Element?.TextColor ?? Color.Default; Color IMaterialEntryRenderer.BackgroundColor => Element?.BackgroundColor ?? Color.Default; } diff --git a/Xamarin.Forms.Material.iOS/NoCaretMaterialTextField.cs b/Xamarin.Forms.Material.iOS/NoCaretMaterialTextField.cs new file mode 100644 index 0000000..c0d1fbb --- /dev/null +++ b/Xamarin.Forms.Material.iOS/NoCaretMaterialTextField.cs @@ -0,0 +1,18 @@ +using CoreGraphics; +using UIKit; +using Xamarin.Forms.Internals; + +namespace Xamarin.Forms.Material.iOS +{ + internal class NoCaretMaterialTextField : MaterialTextField + { + public NoCaretMaterialTextField(IMaterialEntryRenderer element, IFontElement fontElement) : base(element, fontElement) + { + SpellCheckingType = UITextSpellCheckingType.No; + AutocorrectionType = UITextAutocorrectionType.No; + AutocapitalizationType = UITextAutocapitalizationType.None; + } + + public override CGRect GetCaretRectForPosition(UITextPosition position) => new CGRect(); + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Material.iOS/Properties/AssemblyInfo.cs b/Xamarin.Forms.Material.iOS/Properties/AssemblyInfo.cs index 5d90ca2..0e36a7a 100644 --- a/Xamarin.Forms.Material.iOS/Properties/AssemblyInfo.cs +++ b/Xamarin.Forms.Material.iOS/Properties/AssemblyInfo.cs @@ -15,14 +15,14 @@ using Xamarin.Forms; [assembly: AssemblyVersion("2.0.0.0")] [assembly: AssemblyFileVersion("2.0.0.0")] -[assembly: ExportRenderer(typeof(Xamarin.Forms.ActivityIndicator), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialActivityIndicatorRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialButtonRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -[assembly: ExportRenderer(typeof(Xamarin.Forms.Entry), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialEntryRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -[assembly: ExportRenderer(typeof(Xamarin.Forms.Frame), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialFrameRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -[assembly: ExportRenderer(typeof(Xamarin.Forms.ProgressBar), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialProgressBarRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -[assembly: ExportRenderer(typeof(Xamarin.Forms.Slider), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialSliderRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -[assembly: ExportRenderer(typeof(Xamarin.Forms.TimePicker), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialTimePickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -[assembly: ExportRenderer(typeof(Xamarin.Forms.Picker), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialPickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -[assembly: ExportRenderer(typeof(Xamarin.Forms.DatePicker), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialDatePickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -[assembly: ExportRenderer(typeof(Xamarin.Forms.Stepper), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialStepperRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -[assembly: ExportRenderer(typeof(Xamarin.Forms.Editor), typeof(Xamarin.Forms.Platform.iOS.Material.MaterialEditorRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] \ No newline at end of file +[assembly: ExportRenderer(typeof(Xamarin.Forms.ActivityIndicator), typeof(Xamarin.Forms.Material.iOS.MaterialActivityIndicatorRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] +[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(Xamarin.Forms.Material.iOS.MaterialButtonRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] +[assembly: ExportRenderer(typeof(Xamarin.Forms.Entry), typeof(Xamarin.Forms.Material.iOS.MaterialEntryRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] +[assembly: ExportRenderer(typeof(Xamarin.Forms.Frame), typeof(Xamarin.Forms.Material.iOS.MaterialFrameRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] +[assembly: ExportRenderer(typeof(Xamarin.Forms.ProgressBar), typeof(Xamarin.Forms.Material.iOS.MaterialProgressBarRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] +[assembly: ExportRenderer(typeof(Xamarin.Forms.Slider), typeof(Xamarin.Forms.Material.iOS.MaterialSliderRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] +[assembly: ExportRenderer(typeof(Xamarin.Forms.TimePicker), typeof(Xamarin.Forms.Material.iOS.MaterialTimePickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] +[assembly: ExportRenderer(typeof(Xamarin.Forms.Picker), typeof(Xamarin.Forms.Material.iOS.MaterialPickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] +[assembly: ExportRenderer(typeof(Xamarin.Forms.DatePicker), typeof(Xamarin.Forms.Material.iOS.MaterialDatePickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] +[assembly: ExportRenderer(typeof(Xamarin.Forms.Stepper), typeof(Xamarin.Forms.Material.iOS.MaterialStepperRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] +[assembly: ExportRenderer(typeof(Xamarin.Forms.Editor), typeof(Xamarin.Forms.Material.iOS.MaterialEditorRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] diff --git a/Xamarin.Forms.Material.iOS/ReadOnlyMaterialTextField.cs b/Xamarin.Forms.Material.iOS/ReadOnlyMaterialTextField.cs new file mode 100644 index 0000000..f5143cb --- /dev/null +++ b/Xamarin.Forms.Material.iOS/ReadOnlyMaterialTextField.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using ObjCRuntime; +using Foundation; +using Xamarin.Forms.Internals; + +namespace Xamarin.Forms.Material.iOS +{ + internal class ReadOnlyMaterialTextField : NoCaretMaterialTextField + { + readonly HashSet enableActions; + + public ReadOnlyMaterialTextField(IMaterialEntryRenderer element, IFontElement fontElement) : base(element, fontElement) + { + string[] actions = { "copy:", "select:", "selectAll:" }; + enableActions = new HashSet(actions); + } + + public override bool CanPerform(Selector action, NSObject withSender) + => enableActions.Contains(action.Name); + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Material.iOS/Xamarin.Forms.Material.iOS.csproj b/Xamarin.Forms.Material.iOS/Xamarin.Forms.Material.iOS.csproj index 8059c8c..d85b65e 100644 --- a/Xamarin.Forms.Material.iOS/Xamarin.Forms.Material.iOS.csproj +++ b/Xamarin.Forms.Material.iOS/Xamarin.Forms.Material.iOS.csproj @@ -60,6 +60,7 @@ MaterialColors.cs + @@ -67,6 +68,7 @@ + @@ -76,6 +78,7 @@ + diff --git a/Xamarin.Forms.Platform.Android/AppCompat/PickerRenderer.cs b/Xamarin.Forms.Platform.Android/AppCompat/PickerRenderer.cs index 7814fe1..3d3de46 100644 --- a/Xamarin.Forms.Platform.Android/AppCompat/PickerRenderer.cs +++ b/Xamarin.Forms.Platform.Android/AppCompat/PickerRenderer.cs @@ -156,8 +156,8 @@ namespace Xamarin.Forms.Platform.Android.AppCompat } abstract protected void UpdateTextColor(); - abstract protected internal void UpdateTitleColor(); - abstract protected internal void UpdatePlaceHolderText(); + abstract protected void UpdateTitleColor(); + abstract protected void UpdatePlaceHolderText(); } public class PickerRenderer : PickerRendererBase @@ -181,7 +181,7 @@ namespace Xamarin.Forms.Platform.Android.AppCompat protected override EditText EditText => Control; - protected internal override void UpdateTitleColor() + protected override void UpdateTitleColor() { _hintColorSwitcher = _hintColorSwitcher ?? new TextColorSwitcher(EditText.HintTextColors, Element.UseLegacyColorManagement()); _hintColorSwitcher.UpdateTextColor(EditText, Element.TitleColor, EditText.SetHintTextColor); @@ -192,6 +192,6 @@ namespace Xamarin.Forms.Platform.Android.AppCompat _textColorSwitcher = _textColorSwitcher ?? new TextColorSwitcher(EditText.TextColors, Element.UseLegacyColorManagement()); _textColorSwitcher.UpdateTextColor(EditText, Element.TextColor); } - protected internal override void UpdatePlaceHolderText() => EditText.Hint = Element.Title; + protected override void UpdatePlaceHolderText() => EditText.Hint = Element.Title; } } \ No newline at end of file diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialActivityIndicatorRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialActivityIndicatorRenderer.cs index 7d00344..9819c0b 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialActivityIndicatorRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialActivityIndicatorRenderer.cs @@ -7,36 +7,29 @@ using Android.Views; using Android.Widget; using Xamarin.Forms; using Xamarin.Forms.Platform.Android.FastRenderers; -using Xamarin.Forms.Platform.Android.Material; +using Xamarin.Forms.Material.Android; using AProgressBar = Android.Widget.ProgressBar; using AView = Android.Views.View; +using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(ActivityIndicator), typeof(MaterialActivityIndicatorRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialActivityIndicatorRenderer : FrameLayout, IVisualElementRenderer, IViewRenderer, ITabStop { int? _defaultLabelFor; - bool _disposed; - ActivityIndicator _element; CircularProgress _control; - VisualElementTracker _visualElementTracker; VisualElementRenderer _visualElementRenderer; MotionEventHelper _motionEventHelper; - public event EventHandler ElementChanged; - public event EventHandler ElementPropertyChanged; - public MaterialActivityIndicatorRenderer(Context context) : base(context) { - VisualElement.VerifyVisualFlagEnabled(); - _control = new CircularProgress(new ContextThemeWrapper(context, Resource.Style.XamarinFormsMaterialProgressBarCircular), null, Resource.Style.XamarinFormsMaterialProgressBarCircular) { // limiting size to compare iOS realization @@ -51,6 +44,18 @@ namespace Xamarin.Forms.Platform.Android.Material _motionEventHelper = new MotionEventHelper(); } + public event EventHandler ElementChanged; + + public event EventHandler ElementPropertyChanged; + + public override bool OnTouchEvent(MotionEvent e) + { + if (_visualElementRenderer.OnTouchEvent(e) || base.OnTouchEvent(e)) + return true; + + return _motionEventHelper.HandleMotionEvent(Parent, e); + } + protected AProgressBar Control => _control; protected ActivityIndicator Element @@ -90,8 +95,8 @@ namespace Xamarin.Forms.Platform.Android.Material { Element.PropertyChanged -= OnElementPropertyChanged; - if (Platform.GetRenderer(Element) == this) - Element.ClearValue(Platform.RendererProperty); + if (Platform.Android.Platform.GetRenderer(Element) == this) + Element.ClearValue(Platform.Android.Platform.RendererProperty); } } @@ -136,14 +141,6 @@ namespace Xamarin.Forms.Platform.Android.Material UpdateBackgroundColor(); } - public override bool OnTouchEvent(MotionEvent e) - { - if (_visualElementRenderer.OnTouchEvent(e) || base.OnTouchEvent(e)) - return true; - - return _motionEventHelper.HandleMotionEvent(Parent, e); - } - void UpdateIsRunning() { if (Element != null && _control != null) @@ -163,13 +160,9 @@ namespace Xamarin.Forms.Platform.Android.Material } // IVisualElementRenderer - VisualElement IVisualElementRenderer.Element => Element; - VisualElementTracker IVisualElementRenderer.Tracker => _visualElementTracker; - ViewGroup IVisualElementRenderer.ViewGroup => null; - AView IVisualElementRenderer.View => this; SizeRequest IVisualElementRenderer.GetDesiredSize(int widthConstraint, int heightConstraint) @@ -194,12 +187,10 @@ namespace Xamarin.Forms.Platform.Android.Material _visualElementTracker?.UpdateLayout(); // IViewRenderer - void IViewRenderer.MeasureExactly() => ViewRenderer.MeasureExactly(_control, Element, Context); // ITabStop - AView ITabStop.TabStop => _control; } } diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialButtonRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialButtonRenderer.cs index 4cf98b4..466235a 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialButtonRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialButtonRenderer.cs @@ -11,15 +11,16 @@ using Android.Views; using Xamarin.Forms; using Xamarin.Forms.Internals; using Xamarin.Forms.Platform.Android.FastRenderers; -using Xamarin.Forms.Platform.Android.Material; +using Xamarin.Forms.Material.Android; using Xamarin.Forms.PlatformConfiguration.AndroidSpecific; using AColor = Android.Graphics.Color; using AView = Android.Views.View; using MButton = Android.Support.Design.Button.MaterialButton; +using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(MaterialButtonRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialButtonRenderer : MButton, IBorderVisualElementRenderer, IButtonLayoutRenderer, IVisualElementRenderer, IViewRenderer, ITabStop, @@ -31,27 +32,18 @@ namespace Xamarin.Forms.Platform.Android.Material float _defaultFontSize = -1; int? _defaultLabelFor; Typeface _defaultTypeface; - bool _disposed; bool _inputTransparent; - Button _button; - IPlatformElementConfiguration _platformElementConfiguration; VisualElementTracker _tracker; VisualElementRenderer _visualElementRenderer; ButtonLayoutManager _buttonLayoutManager; - readonly AutomationPropertiesProvider _automationPropertiesProvider; - - public event EventHandler ElementChanged; - public event EventHandler ElementPropertyChanged; - + public MaterialButtonRenderer(Context context) : base(new ContextThemeWrapper(context, Resource.Style.XamarinFormsMaterialTheme)) { - VisualElement.VerifyVisualFlagEnabled(); - _automationPropertiesProvider = new AutomationPropertiesProvider(this); _buttonLayoutManager = new ButtonLayoutManager(this, alignIconWithText: true, @@ -68,6 +60,8 @@ namespace Xamarin.Forms.Platform.Android.Material Tag = this; } + public event EventHandler ElementChanged; + public event EventHandler ElementPropertyChanged; protected MButton Control => this; protected Button Element @@ -130,8 +124,8 @@ namespace Xamarin.Forms.Platform.Android.Material { Element.PropertyChanged -= OnElementPropertyChanged; - if (Platform.GetRenderer(Element) == this) - Element.ClearValue(Platform.RendererProperty); + if (Platform.Android.Platform.GetRenderer(Element) == this) + Element.ClearValue(Platform.Android.Platform.RendererProperty); } } @@ -301,7 +295,6 @@ namespace Xamarin.Forms.Platform.Android.Material _platformElementConfiguration ?? (_platformElementConfiguration = Element.OnThisPlatform()); // IOnAttachStateChangeListener - void IOnAttachStateChangeListener.OnViewAttachedToWindow(AView attachedView) => _buttonLayoutManager?.OnViewAttachedToWindow(attachedView); @@ -309,22 +302,18 @@ namespace Xamarin.Forms.Platform.Android.Material _buttonLayoutManager?.OnViewDetachedFromWindow(detachedView); // IOnFocusChangeListener - void IOnFocusChangeListener.OnFocusChange(AView v, bool hasFocus) => Element.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, hasFocus); // IOnClickListener - void IOnClickListener.OnClick(AView v) => ButtonElementManager.OnClick(Element, Element, v); // IOnTouchListener - bool IOnTouchListener.OnTouch(AView v, MotionEvent e) => ButtonElementManager.OnTouch(Element, Element, v, e); // IBorderVisualElementRenderer - float IBorderVisualElementRenderer.ShadowRadius => ShadowRadius; float IBorderVisualElementRenderer.ShadowDx => ShadowDx; float IBorderVisualElementRenderer.ShadowDy => ShadowDy; @@ -336,12 +325,10 @@ namespace Xamarin.Forms.Platform.Android.Material AView IBorderVisualElementRenderer.View => this; // IButtonLayoutRenderer - Button IButtonLayoutRenderer.Element => Element; AppCompatButton IButtonLayoutRenderer.View => this; // IVisualElementRenderer - VisualElement IVisualElementRenderer.Element => Element; VisualElementTracker IVisualElementRenderer.Tracker => _tracker; ViewGroup IVisualElementRenderer.ViewGroup => null; @@ -368,12 +355,10 @@ namespace Xamarin.Forms.Platform.Android.Material _tracker?.UpdateLayout(); // IViewRenderer - void IViewRenderer.MeasureExactly() => ViewRenderer.MeasureExactly(this, Element, Context); // ITabStop - AView ITabStop.TabStop => this; } } diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialColors.cs b/Xamarin.Forms.Platform.Android/Material/MaterialColors.cs index b54b094..238c382 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialColors.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialColors.cs @@ -7,15 +7,17 @@ using Android.Graphics; using AProgressBar = Android.Widget.ProgressBar; using ASeekBar = Android.Widget.AbsSeekBar; using PlatformColor = Android.Graphics.Color; +using Xamarin.Forms.Platform.Android; #else using MaterialComponents; +using Xamarin.Forms.Platform.iOS; using PlatformColor = UIKit.UIColor; #endif #if __ANDROID__ -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android #else -namespace Xamarin.Forms.Platform.iOS.Material +namespace Xamarin.Forms.Material.iOS #endif { // Colors from material-components-android @@ -154,17 +156,39 @@ namespace Xamarin.Forms.Platform.iOS.Material { seekBar.ApplyProgressBarColors(progressColor, backgroundColor); - if (thumbColor.IsDefault) + if (Forms.IsLollipopOrNewer) { - // reset everything to defaults - seekBar.ThumbTintList = seekBar.ProgressTintList; + if (thumbColor.IsDefault) + { + // reset everything to defaults + seekBar.ThumbTintList = seekBar.ProgressTintList; + } + else + { + // handle the case where the thumb is set + var thumb = thumbColor.ToAndroid(); + seekBar.ThumbTintList = ColorStateList.ValueOf(thumb); + } } else { - // handle the case where the thumb is set - var thumb = thumbColor.ToAndroid(); + seekBar.Thumb.SetColorFilter(thumbColor.ToAndroid(), PorterDuff.Mode.SrcIn); + } + } + + internal static void ApplyProgressBarColors(this AProgressBar progressBar, PlatformColor progressColor, PlatformColor backgroundColor, PorterDuff.Mode mode) + { + if(Forms.IsLollipopOrNewer) + { + progressBar.ProgressTintList = ColorStateList.ValueOf(progressColor); + progressBar.ProgressBackgroundTintList = ColorStateList.ValueOf(backgroundColor); + progressBar.ProgressBackgroundTintMode = mode; + } + else + { + (progressBar.Indeterminate ? progressBar.IndeterminateDrawable : + progressBar.ProgressDrawable).SetColorFilter(progressColor, PorterDuff.Mode.SrcIn); - seekBar.ThumbTintList = ColorStateList.ValueOf(thumb); } } @@ -177,18 +201,13 @@ namespace Xamarin.Forms.Platform.iOS.Material if (backgroundColor.IsDefault) { // reset everything to defaults - progressBar.ProgressTintList = ColorStateList.ValueOf(defaultProgress); - progressBar.ProgressBackgroundTintList = ColorStateList.ValueOf(defaultProgress); - progressBar.ProgressBackgroundTintMode = PorterDuff.Mode.SrcIn; + progressBar.ApplyProgressBarColors(defaultProgress, defaultProgress, PorterDuff.Mode.SrcIn); } else { // handle the case where only the background is set var background = backgroundColor.ToAndroid(); - - progressBar.ProgressTintList = ColorStateList.ValueOf(defaultProgress); - progressBar.ProgressBackgroundTintList = ColorStateList.ValueOf(background); - progressBar.ProgressBackgroundTintMode = PorterDuff.Mode.SrcOver; + progressBar.ApplyProgressBarColors(defaultProgress, background, PorterDuff.Mode.SrcOver); } } else @@ -197,20 +216,14 @@ namespace Xamarin.Forms.Platform.iOS.Material { // handle the case where only the progress is set var progress = progressColor.ToAndroid(); - - progressBar.ProgressTintList = ColorStateList.ValueOf(progress); - progressBar.ProgressBackgroundTintList = ColorStateList.ValueOf(progress); - progressBar.ProgressBackgroundTintMode = PorterDuff.Mode.SrcIn; + progressBar.ApplyProgressBarColors(progress, progress, PorterDuff.Mode.SrcIn); } else { // handle the case where both are set var background = backgroundColor.ToAndroid(); var progress = progressColor.ToAndroid(); - - progressBar.ProgressTintList = ColorStateList.ValueOf(progress); - progressBar.ProgressBackgroundTintList = ColorStateList.ValueOf(background); - progressBar.ProgressBackgroundTintMode = PorterDuff.Mode.SrcOver; + progressBar.ApplyProgressBarColors(progress, background, PorterDuff.Mode.SrcOver); } } } diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialContextThemeWrapper.cs b/Xamarin.Forms.Platform.Android/Material/MaterialContextThemeWrapper.cs index d251aff..2763ee0 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialContextThemeWrapper.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialContextThemeWrapper.cs @@ -1,8 +1,9 @@ #if __ANDROID_28__ using Android.Content; using Android.Views; +using Xamarin.Forms.Platform.Android; -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialContextThemeWrapper : ContextThemeWrapper { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialDatePickerRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialDatePickerRenderer.cs index dec29bb..919032d 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialDatePickerRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialDatePickerRenderer.cs @@ -1,15 +1,14 @@ #if __ANDROID_28__ -using System.ComponentModel; using Android.Content; -using Android.Support.V4.View; using Android.Views; using Android.Widget; using Xamarin.Forms; -using Xamarin.Forms.Platform.Android.Material; +using Xamarin.Forms.Material.Android; +using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(Xamarin.Forms.DatePicker), typeof(MaterialDatePickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialDatePickerRenderer : DatePickerRendererBase { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialEditorRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialEditorRenderer.cs index 0f8e69c..9e626db 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialEditorRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialEditorRenderer.cs @@ -4,12 +4,13 @@ using Android.Util; using Android.Views; using Android.Widget; using Xamarin.Forms; -using Xamarin.Forms.Platform.Android.Material; +using Xamarin.Forms.Material.Android; +using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(Xamarin.Forms.Editor), typeof(MaterialEditorRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { - public sealed class MaterialEditorRenderer : EditorRendererBase + public class MaterialEditorRenderer : EditorRendererBase { bool _disposed; MaterialFormsEditText _textInputEditText; @@ -18,12 +19,7 @@ namespace Xamarin.Forms.Platform.Android.Material public MaterialEditorRenderer(Context context) : base(MaterialContextThemeWrapper.Create(context)) { - VisualElement.VerifyVisualFlagEnabled(); - } - - IElementController ElementController => Element as IElementController; - - protected override EditText EditText => _textInputEditText; + } protected override MaterialFormsTextInputLayout CreateNativeControl() { @@ -42,8 +38,6 @@ namespace Xamarin.Forms.Platform.Android.Material UpdateBackgroundColor(); } - protected override void UpdateTextColor() => ApplyTheme(); - protected override void UpdateBackgroundColor() { if (_disposed || _textInputLayout == null) @@ -52,19 +46,20 @@ namespace Xamarin.Forms.Platform.Android.Material _textInputLayout.BoxBackgroundColor = MaterialColors.CreateEntryFilledInputBackgroundColor(Element.BackgroundColor, Element.TextColor); } - protected internal override void UpdatePlaceholderText() + protected override void UpdatePlaceholderText() { if (_disposed || _textInputLayout == null) return; _textInputLayout?.SetHint(Element.Placeholder, Element); } - protected override void UpdatePlaceholderColor() => ApplyTheme(); - void ApplyTheme() => _textInputLayout?.ApplyTheme(Element.TextColor, Element.PlaceholderColor); + protected virtual void ApplyTheme() => _textInputLayout?.ApplyTheme(Element.TextColor, Element.PlaceholderColor); + protected override void UpdateTextColor() => ApplyTheme(); + protected override EditText EditText => _textInputEditText; - protected internal override void UpdateFont() + protected override void UpdateFont() { if (_disposed || _textInputLayout == null) return; diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialEntryRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialEntryRenderer.cs index c83ecf9..ef305ba 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialEntryRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialEntryRenderer.cs @@ -1,15 +1,14 @@ #if __ANDROID_28__ using Android.Content; -using Android.OS; -using Android.Support.V4.View; using Android.Util; using Android.Views; using Android.Widget; using Xamarin.Forms; -using Xamarin.Forms.Platform.Android.Material; +using Xamarin.Forms.Material.Android; +using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(Xamarin.Forms.Entry), typeof(MaterialEntryRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public sealed class MaterialEntryRenderer : EntryRendererBase { @@ -19,13 +18,8 @@ namespace Xamarin.Forms.Platform.Android.Material public MaterialEntryRenderer(Context context) : base(MaterialContextThemeWrapper.Create(context)) { - VisualElement.VerifyVisualFlagEnabled(); } - IElementController ElementController => Element as IElementController; - - protected override EditText EditText => _textInputEditText; - protected override MaterialFormsTextInputLayout CreateNativeControl() { LayoutInflater inflater = LayoutInflater.FromContext(Context); @@ -52,12 +46,8 @@ namespace Xamarin.Forms.Platform.Android.Material _textInputLayout.BoxBackgroundColor = MaterialColors.CreateEntryFilledInputBackgroundColor(Element.BackgroundColor, Element.TextColor); } - protected internal override void UpdatePlaceHolderText() - { - _textInputLayout.SetHint(Element.Placeholder, Element); - } - - + protected internal override void UpdatePlaceHolderText() => _textInputLayout.SetHint(Element.Placeholder, Element); + protected override EditText EditText => _textInputEditText; protected override void UpdatePlaceholderColor() => ApplyTheme(); void ApplyTheme() => _textInputLayout?.ApplyTheme(Element.TextColor, Element.PlaceholderColor); diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialFormsEditText.cs b/Xamarin.Forms.Platform.Android/Material/MaterialFormsEditText.cs index f3a4f42..62b080e 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialFormsEditText.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialFormsEditText.cs @@ -4,8 +4,9 @@ using Android.Content; using Android.Views; using Android.Runtime; using Android.Util; +using Xamarin.Forms.Platform.Android; -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialFormsEditText : MaterialFormsEditTextBase, IFormsEditText { @@ -47,8 +48,8 @@ namespace Xamarin.Forms.Platform.Android.Material remove => _onKeyboardBackPressed -= value; } - event EventHandler _selectionChanged; - event EventHandler IFormsEditText.SelectionChanged + event EventHandler _selectionChanged; + event EventHandler IFormsEditText.SelectionChanged { add => _selectionChanged += value; remove => _selectionChanged -= value; @@ -57,7 +58,7 @@ namespace Xamarin.Forms.Platform.Android.Material protected override void OnSelectionChanged(int selStart, int selEnd) { base.OnSelectionChanged(selStart, selEnd); - _selectionChanged?.Invoke(this, new SelectionChangedEventArgs(selStart, selEnd)); + _selectionChanged?.Invoke(this, new Platform.Android.SelectionChangedEventArgs(selStart, selEnd)); } } } diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialFormsEditTextBase.cs b/Xamarin.Forms.Platform.Android/Material/MaterialFormsEditTextBase.cs index 422cb90..af7aec4 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialFormsEditTextBase.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialFormsEditTextBase.cs @@ -6,8 +6,9 @@ using Android.Views; using Android.Support.Design.Widget; using Android.Runtime; using Android.Util; +using Xamarin.Forms.Platform.Android; -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialFormsEditTextBase : TextInputEditText, IDescendantFocusToggler { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialFormsEditTextManager.cs b/Xamarin.Forms.Platform.Android/Material/MaterialFormsEditTextManager.cs index 983d537..ba92c61 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialFormsEditTextManager.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialFormsEditTextManager.cs @@ -2,13 +2,12 @@ using System; using Android.Content; using Android.Support.Design.Widget; +using Xamarin.Forms.Platform.Android; - -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { internal static class MaterialFormsEditTextManager { - // These paddings are a hack to center the hint // once this issue is resolved we can get rid of these paddings // https://github.com/material-components/material-components-android/issues/120 @@ -19,8 +18,6 @@ namespace Xamarin.Forms.Platform.Android.Material public static void Init(TextInputEditText textInputEditText) { - VisualElement.VerifyVisualFlagEnabled(); - textInputEditText.TextChanged += OnTextChanged; textInputEditText.FocusChange += OnFocusChanged; } diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialFormsTextInputLayout.cs b/Xamarin.Forms.Platform.Android/Material/MaterialFormsTextInputLayout.cs index 48d3150..89c03d8 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialFormsTextInputLayout.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialFormsTextInputLayout.cs @@ -4,7 +4,7 @@ using Android.Content; using Android.Runtime; using Android.Util; -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialFormsTextInputLayout : MaterialFormsTextInputLayoutBase { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialFormsTextInputLayoutBase.cs b/Xamarin.Forms.Platform.Android/Material/MaterialFormsTextInputLayoutBase.cs index f3256fd..db946f4 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialFormsTextInputLayoutBase.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialFormsTextInputLayoutBase.cs @@ -4,12 +4,10 @@ using Android.Content; using Android.Support.Design.Widget; using Android.Runtime; using Android.Util; -using Android.Views; -using Android.Graphics; using Android.Support.V4.View; using Android.Content.Res; -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialFormsTextInputLayoutBase : TextInputLayout { @@ -25,27 +23,18 @@ namespace Xamarin.Forms.Platform.Android.Material public MaterialFormsTextInputLayoutBase(Context context) : base(context) { - Init(); } public MaterialFormsTextInputLayoutBase(Context context, IAttributeSet attrs) : base(context, attrs) { - Init(); } public MaterialFormsTextInputLayoutBase(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr) { - Init(); } protected MaterialFormsTextInputLayoutBase(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { - Init(); - } - - void Init() - { - VisualElement.VerifyVisualFlagEnabled(); } void ResetTextColors(Color formsTextColor, Color formsPlaceHolderColor) @@ -65,7 +54,6 @@ namespace Xamarin.Forms.Platform.Android.Material _focusedFilledColorList = MaterialColors.CreateEntryFilledPlaceholderColors(placeHolderColors.FloatingColor, placeHolderColors.FloatingColor); _unfocusedEmptyColorList = MaterialColors.CreateEntryFilledPlaceholderColors(placeHolderColors.InlineColor, placeHolderColors.FloatingColor); - var textColor = MaterialColors.GetEntryTextColor(formsTextColor).ToArgb(); EditText.SetTextColor(new ColorStateList(s_colorStates, new[] { textColor, textColor })); } @@ -109,7 +97,6 @@ namespace Xamarin.Forms.Platform.Android.Material void OnFocusChange(object sender, FocusChangeEventArgs e) => Device.BeginInvokeOnMainThread(() => ApplyTheme()); - internal void SetHint(string hint, VisualElement element) { if (HintEnabled != !String.IsNullOrWhiteSpace(hint)) @@ -125,7 +112,6 @@ namespace Xamarin.Forms.Platform.Android.Material } } - protected override void Dispose(bool disposing) { if (!_isDisposed) diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialFrameRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialFrameRenderer.cs index f1f9c19..49c0ffd 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialFrameRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialFrameRenderer.cs @@ -6,13 +6,14 @@ using Android.Support.V4.View; using Android.Views; using Xamarin.Forms; using Xamarin.Forms.Platform.Android.FastRenderers; -using Xamarin.Forms.Platform.Android.Material; +using Xamarin.Forms.Material.Android; using AView = Android.Views.View; using MaterialCardView = Android.Support.Design.Card.MaterialCardView; +using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(Xamarin.Forms.Frame), typeof(MaterialFrameRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialFrameRenderer : MaterialCardView, IVisualElementRenderer, IEffectControlProvider, IViewRenderer, ITabStop @@ -23,31 +24,33 @@ namespace Xamarin.Forms.Platform.Android.Material int? _defaultBackgroundColor; int? _defaultStrokeColor; int? _defaultLabelFor; - bool _disposed; - Frame _element; - VisualElementTracker _visualElementTracker; VisualElementPackager _visualElementPackager; - readonly GestureManager _gestureManager; readonly EffectControlProvider _effectControlProvider; readonly MotionEventHelper _motionEventHelper; - public event EventHandler ElementChanged; - public event EventHandler ElementPropertyChanged; - public MaterialFrameRenderer(Context context) : base(new ContextThemeWrapper(context, Resource.Style.XamarinFormsMaterialTheme)) { - VisualElement.VerifyVisualFlagEnabled(); - _gestureManager = new GestureManager(this); _effectControlProvider = new EffectControlProvider(this); _motionEventHelper = new MotionEventHelper(); } + public event EventHandler ElementChanged; + public event EventHandler ElementPropertyChanged; + + public override bool OnTouchEvent(MotionEvent e) + { + if (_gestureManager.OnTouchEvent(e) || base.OnTouchEvent(e)) + return true; + + return _motionEventHelper.HandleMotionEvent(Parent, e); + } + protected MaterialCardView Control => this; protected Frame Element @@ -99,8 +102,8 @@ namespace Xamarin.Forms.Platform.Android.Material { Element.PropertyChanged -= OnElementPropertyChanged; - if (Platform.GetRenderer(Element) == this) - Element.ClearValue(Platform.RendererProperty); + if (Platform.Android.Platform.GetRenderer(Element) == this) + Element.ClearValue(Platform.Android.Platform.RendererProperty); } } @@ -162,20 +165,12 @@ namespace Xamarin.Forms.Platform.Android.Material { if (children[i] is VisualElement visualElement) { - var renderer = Platform.GetRenderer(visualElement); + var renderer = Platform.Android.Platform.GetRenderer(visualElement); renderer?.UpdateLayout(); } } } - public override bool OnTouchEvent(MotionEvent e) - { - if (_gestureManager.OnTouchEvent(e) || base.OnTouchEvent(e)) - return true; - - return _motionEventHelper.HandleMotionEvent(Parent, e); - } - void UpdateShadow() { if (_disposed || Element == null) @@ -256,14 +251,14 @@ namespace Xamarin.Forms.Platform.Android.Material } // IVisualElementRenderer - VisualElement IVisualElementRenderer.Element => Element; - VisualElementTracker IVisualElementRenderer.Tracker => _visualElementTracker; - ViewGroup IVisualElementRenderer.ViewGroup => this; - AView IVisualElementRenderer.View => this; + void IVisualElementRenderer.SetElement(VisualElement element) => + Element = (element as Frame) ?? throw new ArgumentException("Element must be of type Frame."); + void IVisualElementRenderer.UpdateLayout() => + _visualElementTracker?.UpdateLayout(); SizeRequest IVisualElementRenderer.GetDesiredSize(int widthConstraint, int heightConstraint) { @@ -271,9 +266,6 @@ namespace Xamarin.Forms.Platform.Android.Material return new SizeRequest(new Size(context.ToPixels(20), context.ToPixels(20))); } - void IVisualElementRenderer.SetElement(VisualElement element) => - Element = (element as Frame) ?? throw new ArgumentException("Element must be of type Frame."); - void IVisualElementRenderer.SetLabelFor(int? id) { if (_defaultLabelFor == null) @@ -282,21 +274,15 @@ namespace Xamarin.Forms.Platform.Android.Material ViewCompat.SetLabelFor(this, (int)(id ?? _defaultLabelFor)); } - void IVisualElementRenderer.UpdateLayout() => - _visualElementTracker?.UpdateLayout(); - // IEffectControlProvider - void IEffectControlProvider.RegisterEffect(Effect effect) => _effectControlProvider?.RegisterEffect(effect); // IViewRenderer - void IViewRenderer.MeasureExactly() => ViewRenderer.MeasureExactly(this, Element, Context); // ITabStop - AView ITabStop.TabStop => this; } } diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialPickerEditText.cs b/Xamarin.Forms.Platform.Android/Material/MaterialPickerEditText.cs index 55d1014..c8ec1cd 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialPickerEditText.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialPickerEditText.cs @@ -3,34 +3,23 @@ using System; using Android.Content; using Android.Graphics; using Android.Runtime; -using Android.Support.Design.Widget; using Android.Util; using Android.Views; +using Xamarin.Forms.Platform.Android; -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialPickerEditText : MaterialFormsEditTextBase { bool _isDisposed = false; - public MaterialPickerEditText(Context context) : base(context) - { - PickerManager.Init(this); - } - protected MaterialPickerEditText(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) - { - PickerManager.Init(this); - } + public MaterialPickerEditText(Context context) : base(context) => PickerManager.Init(this); - public MaterialPickerEditText(Context context, IAttributeSet attrs) : base(context, attrs) - { - PickerManager.Init(this); - } + protected MaterialPickerEditText(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) => PickerManager.Init(this); - public MaterialPickerEditText(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr) - { - PickerManager.Init(this); - } + public MaterialPickerEditText(Context context, IAttributeSet attrs) : base(context, attrs) => PickerManager.Init(this); + + public MaterialPickerEditText(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr) => PickerManager.Init(this); public override bool OnTouchEvent(MotionEvent e) { @@ -42,7 +31,6 @@ namespace Xamarin.Forms.Platform.Android.Material { base.OnFocusChanged(gainFocus, direction, previouslyFocusedRect); PickerManager.OnFocusChanged(gainFocus, this, (IPopupTrigger)Parent.Parent); - } protected override void Dispose(bool disposing) diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialPickerRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialPickerRenderer.cs index aaa3188..5904f28 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialPickerRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialPickerRenderer.cs @@ -1,17 +1,16 @@ #if __ANDROID_28__ -using System.ComponentModel; using Android.Content; -using Android.Support.V4.View; using Android.Views; using Android.Widget; using Xamarin.Forms; -using Xamarin.Forms.Platform.Android.Material; +using Xamarin.Forms.Material.Android; +using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(Xamarin.Forms.Picker), typeof(MaterialPickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { - public class MaterialPickerRenderer : AppCompat.PickerRendererBase + public class MaterialPickerRenderer : Platform.Android.AppCompat.PickerRendererBase { MaterialPickerTextInputLayout _textInputLayout; MaterialPickerEditText _textInputEditText; @@ -20,7 +19,6 @@ namespace Xamarin.Forms.Platform.Android.Material { } - protected override EditText EditText => _textInputEditText; protected override MaterialPickerTextInputLayout CreateNativeControl() @@ -41,15 +39,10 @@ namespace Xamarin.Forms.Platform.Android.Material _textInputLayout.BoxBackgroundColor = MaterialColors.CreateEntryFilledInputBackgroundColor(Element.BackgroundColor, Element.TextColor); } - protected internal override void UpdatePlaceHolderText() - { - _textInputLayout.SetHint(string.Empty, Element); - } - - protected internal override void UpdateTitleColor() => ApplyTheme(); + protected override void UpdatePlaceHolderText() => _textInputLayout.SetHint(string.Empty, Element); + protected override void UpdateTitleColor() => ApplyTheme(); protected override void UpdateTextColor() => ApplyTheme(); - - void ApplyTheme() => _textInputLayout?.ApplyTheme(Element.TextColor, Color.Default); + protected virtual void ApplyTheme() => _textInputLayout?.ApplyTheme(Element.TextColor, Color.Default); } } #endif \ No newline at end of file diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialPickerTextInputLayout.cs b/Xamarin.Forms.Platform.Android/Material/MaterialPickerTextInputLayout.cs index 3e1648c..95daf93 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialPickerTextInputLayout.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialPickerTextInputLayout.cs @@ -3,8 +3,9 @@ using System; using Android.Content; using Android.Runtime; using Android.Util; +using Xamarin.Forms.Platform.Android; -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialPickerTextInputLayout : MaterialFormsTextInputLayoutBase, IPopupTrigger { diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialProgressBarRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialProgressBarRenderer.cs index 7ec0348..7267d00 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialProgressBarRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialProgressBarRenderer.cs @@ -6,37 +6,29 @@ using Android.Support.V4.View; using Android.Views; using Xamarin.Forms; using Xamarin.Forms.Platform.Android.FastRenderers; -using Xamarin.Forms.Platform.Android.Material; +using Xamarin.Forms.Material.Android; using AProgressBar = Android.Widget.ProgressBar; using AView = Android.Views.View; +using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(ProgressBar), typeof(MaterialProgressBarRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialProgressBarRenderer : AProgressBar, IVisualElementRenderer, IViewRenderer, ITabStop { const int MaximumValue = 10000; - int? _defaultLabelFor; - bool _disposed; - ProgressBar _element; - VisualElementTracker _visualElementTracker; VisualElementRenderer _visualElementRenderer; MotionEventHelper _motionEventHelper; - - public event EventHandler ElementChanged; - public event EventHandler ElementPropertyChanged; - + public MaterialProgressBarRenderer(Context context) : base(new ContextThemeWrapper(context, Resource.Style.XamarinFormsMaterialProgressBarHorizontal), null, Resource.Style.XamarinFormsMaterialProgressBarHorizontal) { - VisualElement.VerifyVisualFlagEnabled(); - Indeterminate = false; Max = MaximumValue; @@ -44,6 +36,17 @@ namespace Xamarin.Forms.Platform.Android.Material _motionEventHelper = new MotionEventHelper(); } + public override bool OnTouchEvent(MotionEvent e) + { + if (_visualElementRenderer.OnTouchEvent(e) || base.OnTouchEvent(e)) + return true; + + return _motionEventHelper.HandleMotionEvent(Parent, e); + } + + public event EventHandler ElementChanged; + public event EventHandler ElementPropertyChanged; + protected AProgressBar Control => this; protected ProgressBar Element @@ -83,8 +86,8 @@ namespace Xamarin.Forms.Platform.Android.Material { Element.PropertyChanged -= OnElementPropertyChanged; - if (Platform.GetRenderer(Element) == this) - Element.ClearValue(Platform.RendererProperty); + if (Platform.Android.Platform.GetRenderer(Element) == this) + Element.ClearValue(Platform.Android.Platform.RendererProperty); } } @@ -125,14 +128,6 @@ namespace Xamarin.Forms.Platform.Android.Material UpdateColors(); } - public override bool OnTouchEvent(MotionEvent e) - { - if (_visualElementRenderer.OnTouchEvent(e) || base.OnTouchEvent(e)) - return true; - - return _motionEventHelper.HandleMotionEvent(Parent, e); - } - void UpdateColors() { if (Element == null || Control == null) @@ -141,20 +136,17 @@ namespace Xamarin.Forms.Platform.Android.Material this.ApplyProgressBarColors(Element.ProgressColor, Element.BackgroundColor); } - void UpdateProgress() - { - Control.Progress = (int)(Element.Progress * MaximumValue); - } + void UpdateProgress() => Control.Progress = (int)(Element.Progress * MaximumValue); // IVisualElementRenderer - VisualElement IVisualElementRenderer.Element => Element; - VisualElementTracker IVisualElementRenderer.Tracker => _visualElementTracker; - ViewGroup IVisualElementRenderer.ViewGroup => null; - AView IVisualElementRenderer.View => this; + void IVisualElementRenderer.SetElement(VisualElement element) => + Element = (element as ProgressBar) ?? throw new ArgumentException("Element must be of type ProgressBar."); + void IVisualElementRenderer.UpdateLayout() => + _visualElementTracker?.UpdateLayout(); SizeRequest IVisualElementRenderer.GetDesiredSize(int widthConstraint, int heightConstraint) { @@ -162,9 +154,6 @@ namespace Xamarin.Forms.Platform.Android.Material return new SizeRequest(new Size(Control.MeasuredWidth, Context.ToPixels(4)), new Size(Context.ToPixels(4), Context.ToPixels(4))); } - void IVisualElementRenderer.SetElement(VisualElement element) => - Element = (element as ProgressBar) ?? throw new ArgumentException("Element must be of type ProgressBar."); - void IVisualElementRenderer.SetLabelFor(int? id) { if (_defaultLabelFor == null) @@ -173,16 +162,11 @@ namespace Xamarin.Forms.Platform.Android.Material ViewCompat.SetLabelFor(this, (int)(id ?? _defaultLabelFor)); } - void IVisualElementRenderer.UpdateLayout() => - _visualElementTracker?.UpdateLayout(); - // IViewRenderer - void IViewRenderer.MeasureExactly() => ViewRenderer.MeasureExactly(this, Element, Context); // ITabStop - AView ITabStop.TabStop => this; } } diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialSliderRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialSliderRenderer.cs index 9f9fcf3..ac5151f 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialSliderRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialSliderRenderer.cs @@ -7,40 +7,31 @@ using Android.Views; using Android.Widget; using Xamarin.Forms; using Xamarin.Forms.Platform.Android.FastRenderers; -using Xamarin.Forms.Platform.Android.Material; +using Xamarin.Forms.Material.Android; using AView = Android.Views.View; +using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(Xamarin.Forms.Slider), typeof(MaterialSliderRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialSliderRenderer : SeekBar, SeekBar.IOnSeekBarChangeListener, IVisualElementRenderer, IViewRenderer, ITabStop { const double MaximumValue = 10000.0; - int? _defaultLabelFor; - bool _disposed; - Slider _element; - VisualElementTracker _visualElementTracker; VisualElementRenderer _visualElementRenderer; MotionEventHelper _motionEventHelper; - double _max = 0.0; double _min = 0.0; - public event EventHandler ElementChanged; - public event EventHandler ElementPropertyChanged; - public MaterialSliderRenderer(Context context) : base(new ContextThemeWrapper(context, Resource.Style.XamarinFormsMaterialSlider), null, Resource.Style.XamarinFormsMaterialSlider) { - VisualElement.VerifyVisualFlagEnabled(); - SetOnSeekBarChangeListener(this); Max = (int)MaximumValue; @@ -48,6 +39,18 @@ namespace Xamarin.Forms.Platform.Android.Material _motionEventHelper = new MotionEventHelper(); } + public event EventHandler ElementChanged; + + public event EventHandler ElementPropertyChanged; + + public override bool OnTouchEvent(MotionEvent e) + { + if (_visualElementRenderer.OnTouchEvent(e) || base.OnTouchEvent(e)) + return true; + + return _motionEventHelper.HandleMotionEvent(Parent, e); + } + protected SeekBar Control => this; protected Slider Element @@ -69,12 +72,6 @@ namespace Xamarin.Forms.Platform.Android.Material } } - double Value - { - get { return _min + (_max - _min) * (Control.Progress / MaximumValue); } - set { Control.Progress = (int)((value - _min) / (_max - _min) * MaximumValue); } - } - protected override void Dispose(bool disposing) { if (_disposed) @@ -88,13 +85,14 @@ namespace Xamarin.Forms.Platform.Android.Material _visualElementRenderer?.Dispose(); _visualElementRenderer = null; + SetOnSeekBarChangeListener(null); if (Element != null) { Element.PropertyChanged -= OnElementPropertyChanged; - if (Platform.GetRenderer(Element) == this) - Element.ClearValue(Platform.RendererProperty); + if (Platform.Android.Platform.GetRenderer(Element) == this) + Element.ClearValue(Platform.Android.Platform.RendererProperty); } } @@ -136,14 +134,6 @@ namespace Xamarin.Forms.Platform.Android.Material UpdateColors(); } - public override bool OnTouchEvent(MotionEvent e) - { - if (_visualElementRenderer.OnTouchEvent(e) || base.OnTouchEvent(e)) - return true; - - return _motionEventHelper.HandleMotionEvent(Parent, e); - } - void UpdateColors() { if (Element == null || Control == null) @@ -157,7 +147,12 @@ namespace Xamarin.Forms.Platform.Android.Material this.ApplySeekBarColors(progressColor, backgroundColor, thumbColor); } - + + double Value + { + get { return _min + (_max - _min) * (Control.Progress / MaximumValue); } + set { Control.Progress = (int)((value - _min) / (_max - _min) * MaximumValue); } + } void UpdateValue() { _min = Element.Minimum; @@ -166,32 +161,25 @@ namespace Xamarin.Forms.Platform.Android.Material } // SeekBar.IOnSeekBarChangeListener - void SeekBar.IOnSeekBarChangeListener.OnProgressChanged(SeekBar seekBar, int progress, bool fromUser) { if (fromUser) ((IElementController)Element).SetValueFromRenderer(Slider.ValueProperty, Value); } - void SeekBar.IOnSeekBarChangeListener.OnStartTrackingTouch(SeekBar seekBar) - { - ((ISliderController)Element)?.SendDragStarted(); - } + void SeekBar.IOnSeekBarChangeListener.OnStartTrackingTouch(SeekBar seekBar) => ((ISliderController)Element)?.SendDragStarted(); - void SeekBar.IOnSeekBarChangeListener.OnStopTrackingTouch(SeekBar seekBar) - { - ((ISliderController)Element)?.SendDragCompleted(); - } + void SeekBar.IOnSeekBarChangeListener.OnStopTrackingTouch(SeekBar seekBar) => ((ISliderController)Element)?.SendDragCompleted(); // IVisualElementRenderer - VisualElement IVisualElementRenderer.Element => Element; - VisualElementTracker IVisualElementRenderer.Tracker => _visualElementTracker; - ViewGroup IVisualElementRenderer.ViewGroup => null; - AView IVisualElementRenderer.View => this; + void IVisualElementRenderer.SetElement(VisualElement element) => + Element = (element as Slider) ?? throw new ArgumentException($"Element must be of type {nameof(Slider)}."); + void IVisualElementRenderer.UpdateLayout() => + _visualElementTracker?.UpdateLayout(); SizeRequest IVisualElementRenderer.GetDesiredSize(int widthConstraint, int heightConstraint) { @@ -199,9 +187,6 @@ namespace Xamarin.Forms.Platform.Android.Material return new SizeRequest(new Size(Control.MeasuredWidth, Control.MeasuredHeight), new Size()); } - void IVisualElementRenderer.SetElement(VisualElement element) => - Element = (element as Slider) ?? throw new ArgumentException($"Element must be of type {nameof(Slider)}."); - void IVisualElementRenderer.SetLabelFor(int? id) { if (_defaultLabelFor == null) @@ -210,16 +195,12 @@ namespace Xamarin.Forms.Platform.Android.Material ViewCompat.SetLabelFor(this, (int)(id ?? _defaultLabelFor)); } - void IVisualElementRenderer.UpdateLayout() => - _visualElementTracker?.UpdateLayout(); // IViewRenderer - void IViewRenderer.MeasureExactly() => ViewRenderer.MeasureExactly(this, Element, Context); // ITabStop - AView ITabStop.TabStop => this; } } diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialStepperRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialStepperRenderer.cs index 7eede34..d576377 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialStepperRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialStepperRenderer.cs @@ -4,13 +4,14 @@ using Android.Content; using Android.Views; using Android.Widget; using Xamarin.Forms; -using Xamarin.Forms.Platform.Android.Material; +using Xamarin.Forms.Material.Android; +using Xamarin.Forms.Platform.Android; using AButton = Android.Widget.Button; using MButton = Android.Support.Design.Button.MaterialButton; [assembly: ExportRenderer(typeof(Xamarin.Forms.Stepper), typeof(MaterialStepperRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialStepperRenderer : ViewRenderer, IStepperRenderer { @@ -21,8 +22,6 @@ namespace Xamarin.Forms.Platform.Android.Material public MaterialStepperRenderer(Context context) : base(context) { - VisualElement.VerifyVisualFlagEnabled(); - AutoPackage = false; } diff --git a/Xamarin.Forms.Platform.Android/Material/MaterialTimePickerRenderer.cs b/Xamarin.Forms.Platform.Android/Material/MaterialTimePickerRenderer.cs index a3c6eac..2723388 100644 --- a/Xamarin.Forms.Platform.Android/Material/MaterialTimePickerRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Material/MaterialTimePickerRenderer.cs @@ -1,15 +1,14 @@ #if __ANDROID_28__ -using System.ComponentModel; using Android.Content; -using Android.Support.V4.View; using Android.Views; using Android.Widget; using Xamarin.Forms; -using Xamarin.Forms.Platform.Android.Material; +using Xamarin.Forms.Material.Android; +using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(Xamarin.Forms.TimePicker), typeof(MaterialTimePickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })] -namespace Xamarin.Forms.Platform.Android.Material +namespace Xamarin.Forms.Material.Android { public class MaterialTimePickerRenderer : TimePickerRendererBase { diff --git a/Xamarin.Forms.Platform.Android/Renderers/CircularProgress.cs b/Xamarin.Forms.Platform.Android/Renderers/CircularProgress.cs index 52293cb..7293c4f 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/CircularProgress.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/CircularProgress.cs @@ -42,7 +42,15 @@ namespace Xamarin.Forms.Platform.Android public void SetColor(Color color) { var progress = color.IsDefault ? DefaultColor : color.ToAndroid(); - IndeterminateTintList = ColorStateList.ValueOf(progress); + + if (Forms.IsLollipopOrNewer) + { + IndeterminateTintList = ColorStateList.ValueOf(progress); + } + else + { + (Indeterminate ? IndeterminateDrawable : ProgressDrawable).SetColorFilter(color.ToAndroid(), PorterDuff.Mode.SrcIn); + } } public void SetBackgroundColor(Color color) diff --git a/Xamarin.Forms.Platform.Android/Renderers/DatePickerRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/DatePickerRenderer.cs index 27e56ed..cce0a5b 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/DatePickerRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/DatePickerRenderer.cs @@ -54,11 +54,6 @@ namespace Xamarin.Forms.Platform.Android base.Dispose(disposing); } - public override bool DispatchTouchEvent(MotionEvent e) - { - return base.DispatchTouchEvent(e); - } - protected override void OnElementChanged(ElementChangedEventArgs e) { base.OnElementChanged(e); diff --git a/Xamarin.Forms.Platform.Android/Renderers/EditorRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/EditorRenderer.cs index 9bf07a4..55e1f04 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/EditorRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/EditorRenderer.cs @@ -199,7 +199,7 @@ namespace Xamarin.Forms.Platform.Android ElementController.SendCompleted(); } - protected internal virtual void UpdateFont() + protected virtual void UpdateFont() { EditText.Typeface = Element.ToTypeface(); EditText.SetTextSize(ComplexUnitType.Sp, (float)Element.FontSize); @@ -245,7 +245,7 @@ namespace Xamarin.Forms.Platform.Android abstract protected void UpdateTextColor(); - internal protected virtual void UpdatePlaceholderText() + protected virtual void UpdatePlaceholderText() { if (EditText.Hint == Element.Placeholder) return; diff --git a/Xamarin.Forms.Platform.Android/Resources/Layout/MaterialPickerTextInput.axml b/Xamarin.Forms.Platform.Android/Resources/Layout/MaterialPickerTextInput.axml index fc3f9fd..7e8ef92 100644 --- a/Xamarin.Forms.Platform.Android/Resources/Layout/MaterialPickerTextInput.axml +++ b/Xamarin.Forms.Platform.Android/Resources/Layout/MaterialPickerTextInput.axml @@ -1,12 +1,12 @@ - - - + diff --git a/Xamarin.Forms.Platform.Android/Resources/Layout/TextInputLayoutFilledBox.axml b/Xamarin.Forms.Platform.Android/Resources/Layout/TextInputLayoutFilledBox.axml index cbb68ff..d4a01fc 100644 --- a/Xamarin.Forms.Platform.Android/Resources/Layout/TextInputLayoutFilledBox.axml +++ b/Xamarin.Forms.Platform.Android/Resources/Layout/TextInputLayoutFilledBox.axml @@ -1,12 +1,12 @@ - - - + diff --git a/Xamarin.Forms.Platform.Android/Resources/drawable/MaterialActivityIndicatorBackground.xml b/Xamarin.Forms.Platform.Android/Resources/drawable-v21/MaterialActivityIndicatorBackground.xml similarity index 100% rename from Xamarin.Forms.Platform.Android/Resources/drawable/MaterialActivityIndicatorBackground.xml rename to Xamarin.Forms.Platform.Android/Resources/drawable-v21/MaterialActivityIndicatorBackground.xml diff --git a/Xamarin.Forms.Platform.Android/Resources/values-v21/styles.xml b/Xamarin.Forms.Platform.Android/Resources/values-v21/styles.xml new file mode 100644 index 0000000..e183a76 --- /dev/null +++ b/Xamarin.Forms.Platform.Android/Resources/values-v21/styles.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/Xamarin.Forms.Platform.Android/Resources/values/styles.xml b/Xamarin.Forms.Platform.Android/Resources/values/styles.xml index 118b50f..338242f 100644 --- a/Xamarin.Forms.Platform.Android/Resources/values/styles.xml +++ b/Xamarin.Forms.Platform.Android/Resources/values/styles.xml @@ -19,7 +19,6 @@ @drawable/MaterialProgressBar