From b8bffb6c794858bbd5497c5ee7ce7ff65db97429 Mon Sep 17 00:00:00 2001 From: Pavel Yakovlev Date: Mon, 17 Jun 2019 04:43:11 -0700 Subject: [PATCH] [Android] Fixes work IsClippedToBounds on (Fast Renderer) Frame (#6358) fixes #3150 fixes #6447 * [Android] Fixes work IsClippedToBounds on (Fast Renderer) Frame - fixes float values in Dynamic ViewGallery * added on-screen instructions for test * added API check * added SetClipToOutline to ViewExtensions * added button to toggle IsClippedToBounds --- .../Issue3150.cs | 48 ++++++++++++++ ...rin.Forms.Controls.Issues.Shared.projitems | 1 + .../GalleryPages/DynamicViewGallery.cs | 64 ++++++++++++++++--- .../FastRenderers/FrameRenderer.cs | 5 ++ .../ViewExtensions.cs | 16 +++++ 5 files changed, 125 insertions(+), 9 deletions(-) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue3150.cs diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue3150.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue3150.cs new file mode 100644 index 000000000..528181ef2 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue3150.cs @@ -0,0 +1,48 @@ +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + +namespace Xamarin.Forms.Controls.Issues +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 3150, "IsClippedToBounds on (Fast Renderer) Frame not working", PlatformAffected.Android)] + + class Issue3150 : TestContentPage + { + protected override void Init() + { + const string buttonText = "Toggle IsClippedToBounds: "; + var frame = new Frame + { + BackgroundColor = Color.Blue, + HorizontalOptions = LayoutOptions.CenterAndExpand, + VerticalOptions = LayoutOptions.CenterAndExpand, + IsClippedToBounds = false, + Content = new BoxView + { + BackgroundColor = Color.Yellow, + TranslationX = 50 + } + }; + + Button button = null; + button = new Button() + { + Text = $"{buttonText}{frame.IsClippedToBounds}", + Command = new Command(() => + { + frame.IsClippedToBounds = !frame.IsClippedToBounds; + button.Text = $"{buttonText}{frame.IsClippedToBounds}"; + }) + }; + + Content = new StackLayout + { + Children = { + new Label { Text = "If the yellow box extends past the end of the blue box, the test has passed" }, + frame, + button + } + }; + } + } +} 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 4e3b90dbc..f6cb8a43d 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 @@ -9,6 +9,7 @@ Xamarin.Forms.Controls.Issues + diff --git a/Xamarin.Forms.Controls/GalleryPages/DynamicViewGallery.cs b/Xamarin.Forms.Controls/GalleryPages/DynamicViewGallery.cs index b8a6791f0..ed027d633 100644 --- a/Xamarin.Forms.Controls/GalleryPages/DynamicViewGallery.cs +++ b/Xamarin.Forms.Controls/GalleryPages/DynamicViewGallery.cs @@ -12,6 +12,14 @@ namespace Xamarin.Forms.Controls internal static Dictionary ctor, NamedAction[] methods)> TestedTypes = new Dictionary ctor, NamedAction[] methods)> { { nameof(ActivityIndicator), (() => new ActivityIndicator() { IsRunning = false }, null) }, + { nameof(Frame), (() => new Frame { + BackgroundColor = Color.Blue, + Content = new BoxView + { + BackgroundColor = Color.Yellow, + TranslationX = 50 + } + }, null) }, { nameof(ProgressBar), (() => new ProgressBar(), null) }, { nameof(Button), (() => new Button { Text = "Button" }, null) }, { nameof(Label), (() => new Label { Text = "label" }, null) }, @@ -142,7 +150,9 @@ namespace Xamarin.Forms.Controls } else if (property.PropertyType == typeof(double) || property.PropertyType == typeof(float) || - property.PropertyType == typeof(int)) + property.PropertyType == typeof(int) || + property.PropertyType == typeof(uint) || + property.PropertyType == typeof(long)) { propertyLayout.Children.Add( CreateValuePicker(property, bindableProperties.FirstOrDefault(p => p.PropertyName == property.Name), element)); @@ -225,8 +235,30 @@ namespace Xamarin.Forms.Controls max = _minMaxProperties[property.Name].max; } - var isInt = property.PropertyType == typeof(int); - var value = isInt ? (int)property.GetValue(element) : (double)property.GetValue(element); + var stringFormat = "0"; + var objectValue = property.GetValue(element); + double value = 0; + switch (objectValue) + { + case int i: + value = i; + break; + case uint ui: + value = ui; + break; + case long l: + value = l; + break; + case float f: + value = f; + stringFormat += ".#"; + break; + case double d: + value = d; + stringFormat += ".#"; + break; + } + var slider = new Slider(min, max, value); var actions = new Grid @@ -260,17 +292,31 @@ namespace Xamarin.Forms.Controls var valueLabel = new Label { - Text = slider.Value.ToString(isInt ? "0" : "0.#"), + Text = slider.Value.ToString(stringFormat), HorizontalOptions = LayoutOptions.End }; slider.ValueChanged += (_, e) => { - if (isInt) - property.SetValue(element, (int)e.NewValue); - else - property.SetValue(element, e.NewValue); - valueLabel.Text = e.NewValue.ToString(isInt ? "0" : "0.#"); + switch (objectValue) + { + case int i: + property.SetValue(element, (int)e.NewValue); + break; + case uint ui: + property.SetValue(element, (uint)e.NewValue); + break; + case long l: + property.SetValue(element, (long)e.NewValue); + break; + case float f: + property.SetValue(element, (float)e.NewValue); + break; + case double d: + property.SetValue(element, e.NewValue); + break; + } + valueLabel.Text = e.NewValue.ToString(stringFormat); }; actions.AddChild(slider, 0, 1); diff --git a/Xamarin.Forms.Platform.Android/FastRenderers/FrameRenderer.cs b/Xamarin.Forms.Platform.Android/FastRenderers/FrameRenderer.cs index aa1b24fa7..5d28e1377 100644 --- a/Xamarin.Forms.Platform.Android/FastRenderers/FrameRenderer.cs +++ b/Xamarin.Forms.Platform.Android/FastRenderers/FrameRenderer.cs @@ -191,6 +191,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers UpdateBackgroundColor(); UpdateCornerRadius(); UpdateBorderColor(); + UpdateClippedToBounds(); ElevationHelper.SetElevation(this, e.NewElement); } @@ -234,8 +235,12 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers UpdateCornerRadius(); else if (e.PropertyName == Frame.BorderColorProperty.PropertyName) UpdateBorderColor(); + else if (e.Is(Xamarin.Forms.Layout.IsClippedToBoundsProperty)) + UpdateClippedToBounds(); } + void UpdateClippedToBounds() => this.SetClipToOutline(Element.IsClippedToBounds); + void UpdateBackgroundColor() { if (_disposed) diff --git a/Xamarin.Forms.Platform.Android/ViewExtensions.cs b/Xamarin.Forms.Platform.Android/ViewExtensions.cs index 891467051..ed540e533 100644 --- a/Xamarin.Forms.Platform.Android/ViewExtensions.cs +++ b/Xamarin.Forms.Platform.Android/ViewExtensions.cs @@ -77,5 +77,21 @@ namespace Xamarin.Forms.Platform.Android view.Id = Platform.GenerateViewId(); } } + + public static bool GetClipToOutline(this AView view) + { + if (view.IsDisposed() || !Forms.IsLollipopOrNewer) + return false; + + return view.ClipToOutline; + } + + public static void SetClipToOutline(this AView view, bool value) + { + if (view.IsDisposed() || !Forms.IsLollipopOrNewer) + return; + + view.ClipToOutline = value; + } } } \ No newline at end of file