[Android] Use Fast Renderers by Default (#5926)
authorSamantha Houts <samhouts@users.noreply.github.com>
Sat, 27 Apr 2019 19:15:39 +0000 (12:15 -0700)
committerGitHub <noreply@github.com>
Sat, 27 Apr 2019 19:15:39 +0000 (12:15 -0700)
* [Android] Unseal FastRenderers

* [Android] Flip experimental flag to legacy flag

* Flip flag for testing both renderers & set up custom renderers for testing

* Undo build arg change

This reverts commit 8447fec03b4dff16d8ca96544ec83159670b80d7.

* Fix whitespace

* restore workaround for #2520

* Only use workaround for fast renderers (crashes legacy)

fixes #5724

13 files changed:
Xamarin.Forms.ControlGallery.Android/CustomRenderers.cs
Xamarin.Forms.ControlGallery.Android/DisposeLabelRenderer.cs
Xamarin.Forms.ControlGallery.Android/FormsAppCompatActivity.cs
Xamarin.Forms.ControlGallery.Android/_1909CustomRenderer.cs
Xamarin.Forms.ControlGallery.Android/_5724CustomRenderers.cs [new file with mode: 0644]
Xamarin.Forms.ControlGallery.Android/_60122ImageRenderer.cs
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5724.cs [new file with mode: 0644]
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
Xamarin.Forms.Platform.Android/AppCompat/FormsAppCompatActivity.cs
Xamarin.Forms.Platform.Android/FastRenderers/ButtonRenderer.cs
Xamarin.Forms.Platform.Android/FastRenderers/ImageRenderer.cs
Xamarin.Forms.Platform.Android/FastRenderers/LabelRenderer.cs
Xamarin.Forms.Platform.Android/Flags.cs

index cf0098f..1d41e2a 100644 (file)
@@ -69,16 +69,28 @@ namespace Xamarin.Forms.ControlGallery.Android
                }
        }
 
-       public class AttachedStateEffectLabelRenderer : LabelRenderer
+       public class AttachedStateEffectLabelRenderer :
+#if TEST_EXPERIMENTAL_RENDERERS
+               Platform.Android.FastRenderers.LabelRenderer
+#else
+               LabelRenderer
+#endif
        {
                public AttachedStateEffectLabelRenderer(Context context) : base(context)
                {
                }
 
+#if TEST_EXPERIMENTAL_RENDERERS
                protected override void Dispose(bool disposing)
                {
+                       foreach (var effect in Element.Effects.OfType<Controls.Effects.AttachedStateEffect>())
+                       {
+                               effect.Detached(Element);
+                       }
+
                        base.Dispose(disposing);
                }
+#endif
        }
 
        public class NativeDroidMasterDetail : Xamarin.Forms.Platform.Android.AppCompat.MasterDetailPageRenderer
@@ -680,7 +692,7 @@ namespace Xamarin.Forms.ControlGallery.Android
 
                protected override void Dispose(bool disposing)
                {
-                       if(disposing)
+                       if (disposing)
                        {
                                ViewGroup.ViewTreeObserver.RemoveOnGlobalLayoutListener(this);
                                _gridChild.SetOnTouchListener(null);
index 4a6364c..3e97ee0 100644 (file)
@@ -4,7 +4,12 @@ using Xamarin.Forms.Platform.Android;
 namespace Xamarin.Forms.ControlGallery.Android
 {
 #pragma warning disable 618
-       public class DisposeLabelRenderer : LabelRenderer
+       public class DisposeLabelRenderer :
+#if TEST_EXPERIMENTAL_RENDERERS
+               Platform.Android.FastRenderers.LabelRenderer
+#else
+               LabelRenderer
+#endif
 #pragma warning restore 618
        {
                protected override void Dispose (bool disposing)
index 4ab1eb1..2ee5a7c 100644 (file)
@@ -41,12 +41,10 @@ namespace Xamarin.Forms.ControlGallery.Android
                        base.OnCreate(bundle);
 
 #if TEST_EXPERIMENTAL_RENDERERS
-                       // CollectionView lets us test CollectionView stuff until it's officially released
-                       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", "Shell_Experimental" */); 
+                       Forms.SetFlags("Fake_Flag"/*, "CollectionView_Experimental", "Shell_Experimental"*/); 
+#else
+                       Forms.SetFlags("UseLegacyRenderers"/*, "CollectionView_Experimental", "Shell_Experimental" */);
 #endif
                        Forms.Init(this, bundle);
 
index fbfc4e0..eda38cd 100644 (file)
@@ -9,8 +9,13 @@ using Xamarin.Forms.Controls.Issues;
 [assembly: ExportRenderer(typeof(Issue1909.FlatButton), typeof(FlatButtonRenderer))]
 namespace Xamarin.Forms.ControlGallery.Android
 {
-               public class FlatButtonRenderer : ButtonRenderer
-               {
+               public class FlatButtonRenderer :
+#if TEST_EXPERIMENTAL_RENDERERS
+               Platform.Android.FastRenderers.ButtonRenderer
+#else
+               ButtonRenderer
+#endif
+       {
                        public FlatButtonRenderer(Context context) : base(context)
                        {
                        }
diff --git a/Xamarin.Forms.ControlGallery.Android/_5724CustomRenderers.cs b/Xamarin.Forms.ControlGallery.Android/_5724CustomRenderers.cs
new file mode 100644 (file)
index 0000000..5bbab9a
--- /dev/null
@@ -0,0 +1,98 @@
+using Android.Content;
+using System;
+using System.Linq;
+using Xamarin.Forms;
+using Xamarin.Forms.ControlGallery.Android;
+using Xamarin.Forms.Platform.Android.AppCompat;
+using Xamarin.Forms.Controls.Issues;
+using System.ComponentModel;
+
+[assembly: ExportRenderer(typeof(Issue5724.CustomButton), typeof(CustomButtonRenderer5724))]
+namespace Xamarin.Forms.ControlGallery.Android
+{
+       public class CustomButtonRenderer5724 :
+#if TEST_EXPERIMENTAL_RENDERERS
+               Platform.Android.FastRenderers.ButtonRenderer
+#else
+               ButtonRenderer
+#endif
+       {
+               public CustomButtonRenderer5724(Context context) : base(context)
+               {
+               }
+
+               protected override void OnElementChanged(Platform.Android.ElementChangedEventArgs<Button> e)
+               {
+                       base.OnElementChanged(e);
+               }
+               protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+               {
+                       base.OnElementPropertyChanged(sender, e);
+               }
+       }
+
+       public class CustomImageRenderer5724 :
+#if TEST_EXPERIMENTAL_RENDERERS
+               Platform.Android.FastRenderers.ImageRenderer
+#else
+               ImageRenderer
+#endif
+       {
+               public CustomImageRenderer5724(Context context) : base(context)
+               {
+               }
+
+               protected override void OnElementChanged(Platform.Android.ElementChangedEventArgs<Image> e)
+               {
+                       base.OnElementChanged(e);
+               }
+               protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+               {
+                       base.OnElementPropertyChanged(sender, e);
+               }
+       }
+
+       public class CustomFrameRenderer5724 :
+#if TEST_EXPERIMENTAL_RENDERERS
+               Platform.Android.FastRenderers.FrameRenderer
+#else
+               FrameRenderer
+#endif
+       {
+               public CustomFrameRenderer5724(Context context) : base(context)
+               {
+               }
+
+               protected override void OnElementChanged(Platform.Android.ElementChangedEventArgs<Frame> e)
+               {
+                       base.OnElementChanged(e);
+               }
+
+               protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+               {
+                       base.OnElementPropertyChanged(sender, e);
+               }
+
+       }
+
+       public class CustomLabelRenderer5724 :
+#if TEST_EXPERIMENTAL_RENDERERS
+               Platform.Android.FastRenderers.LabelRenderer
+#else
+               LabelRenderer
+#endif
+       {
+               public CustomLabelRenderer5724(Context context) : base(context)
+               {
+               }
+
+               protected override void OnElementChanged(Platform.Android.ElementChangedEventArgs<Label> e)
+               {
+                       base.OnElementChanged(e);
+               }
+               protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+               {
+                       base.OnElementPropertyChanged(sender, e);
+               }
+       }
+}
\ No newline at end of file
index e537e15..ee91aa4 100644 (file)
@@ -10,7 +10,13 @@ using Xamarin.Forms.Platform.Android;
 
 namespace Xamarin.Forms.ControlGallery.Android
 {
-       public class _60122ImageRenderer : ImageRenderer 
+       public class _60122ImageRenderer :
+#if TEST_EXPERIMENTAL_RENDERERS
+               Platform.Android.FastRenderers.ImageRenderer
+#else
+               ImageRenderer
+#endif
+
        {
                public _60122ImageRenderer(Context context) : base(context)
                {
@@ -30,7 +36,7 @@ namespace Xamarin.Forms.ControlGallery.Android
                        if (e.NewElement != null)
                        {
                                _customControl = e.NewElement as Bugzilla60122._60122Image;
-                       
+
                                LongClick += LongPressGestureRecognizerImageRenderer_LongClick;
                        }
                        else
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5724.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5724.cs
new file mode 100644 (file)
index 0000000..ed99a65
--- /dev/null
@@ -0,0 +1,40 @@
+using Xamarin.Forms.CustomAttributes;
+using Xamarin.Forms.Internals;
+
+namespace Xamarin.Forms.Controls.Issues
+{
+       [Preserve(AllMembers = true)]
+       [Issue(IssueTracker.Github, 5724, "Use Android Fast Renderers by Default", PlatformAffected.Android)]
+       public class Issue5724 : TestContentPage
+       {
+               public class CustomButton : Button { }
+               public class CustomImage : Image { }
+               public class CustomLabel : Label { }
+               public class CustomFrame : Frame { }
+
+               protected override void Init()
+               {
+                       Content = new StackLayout
+                       {
+                               Children =
+                               {
+                                       new CustomLabel
+                                       {
+                                               Text = "See if I'm here"
+                                       },
+                                       new CustomButton
+                                       {
+                                               Text = "See if I'm here"
+                                       },
+                                       new CustomFrame
+                                       {
+                                       },
+                                       new CustomImage
+                                       {
+                                               Source = "coffee.png"
+                                       },
+                               }
+                       };
+               }
+       }
+}
\ No newline at end of file
index 062a886..c5bee2d 100644 (file)
       <DependentUpon>VisualControlsPage.xaml</DependentUpon>
     </Compile>
     <Compile Include="$(MSBuildThisFileDirectory)Issue5470.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Issue5724.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)_Template.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Bugzilla56298.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Bugzilla42620.cs" />
index e774ab0..d39df26 100644 (file)
@@ -101,18 +101,18 @@ namespace Xamarin.Forms.Platform.Android
                        RegisterHandler(typeof(Picker), typeof(AppCompat.PickerRenderer), typeof(PickerRenderer));
                        RegisterHandler(typeof(CarouselPage), typeof(AppCompat.CarouselPageRenderer), typeof(CarouselPageRenderer));
 
-                       if (Forms.Flags.Contains(Flags.FastRenderersExperimental))
+                       if (Forms.Flags.Contains(Flags.UseLegacyRenderers))
+                       {
+                               RegisterHandler(typeof(Button), typeof(AppCompat.ButtonRenderer), typeof(ButtonRenderer));
+                               RegisterHandler(typeof(Frame), typeof(AppCompat.FrameRenderer), typeof(FrameRenderer));
+                       }
+                       else
                        {
                                RegisterHandler(typeof(Button), typeof(FastRenderers.ButtonRenderer), typeof(ButtonRenderer));
                                RegisterHandler(typeof(Label), typeof(FastRenderers.LabelRenderer), typeof(LabelRenderer));
                                RegisterHandler(typeof(Image), typeof(FastRenderers.ImageRenderer), typeof(ImageRenderer));
                                RegisterHandler(typeof(Frame), typeof(FastRenderers.FrameRenderer), typeof(FrameRenderer));
                        }
-                       else
-                       {
-                               RegisterHandler(typeof(Button), typeof(AppCompat.ButtonRenderer), typeof(ButtonRenderer));
-                               RegisterHandler(typeof(Frame), typeof(AppCompat.FrameRenderer), typeof(FrameRenderer));
-                       }
                }
 
                protected void LoadApplication(Application application)
index 4e9a4b3..cfba741 100644 (file)
@@ -13,7 +13,7 @@ using AView = Android.Views.View;
 
 namespace Xamarin.Forms.Platform.Android.FastRenderers
 {
-       internal sealed class ButtonRenderer : AppCompatButton,
+       public class ButtonRenderer : AppCompatButton,
                IBorderVisualElementRenderer, IButtonLayoutRenderer, IVisualElementRenderer, IViewRenderer, ITabStop,
                AView.IOnAttachStateChangeListener, AView.IOnFocusChangeListener, AView.IOnClickListener, AView.IOnTouchListener
        {
@@ -46,7 +46,12 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
                        Initialize();
                }
 
-               public VisualElement Element => Button;
+               protected Button Element => Button;
+               protected AppCompatButton Control => this;
+
+               VisualElement IBorderVisualElementRenderer.Element => Element;
+
+               VisualElement IVisualElementRenderer.Element => Element;
                AView IVisualElementRenderer.View => this;
                ViewGroup IVisualElementRenderer.ViewGroup => null;
                VisualElementTracker IVisualElementRenderer.Tracker => _tracker;
@@ -191,7 +196,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
                        return new Size();
                }
 
-               void OnElementChanged(ElementChangedEventArgs<Button> e)
+               protected virtual void OnElementChanged(ElementChangedEventArgs<Button> e)
                {
                        if (e.NewElement != null && !_isDisposed)
                        {
@@ -212,7 +217,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
                        ElementChanged?.Invoke(this, new VisualElementChangedEventArgs(e.OldElement, e.NewElement));
                }
 
-               void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+               protected virtual void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
                {
                        if (e.PropertyName == Button.TextColorProperty.PropertyName)
                        {
index 77003e4..76c8cf8 100644 (file)
@@ -11,7 +11,7 @@ using Android.Support.V4.View;
 
 namespace Xamarin.Forms.Platform.Android.FastRenderers
 {
-       internal sealed class ImageRenderer : AImageView, IVisualElementRenderer, IImageRendererController, IViewRenderer, ITabStop,
+       public class ImageRenderer : AImageView, IVisualElementRenderer, IImageRendererController, IViewRenderer, ITabStop,
                ILayoutChanges
        {
                bool _disposed;
@@ -70,7 +70,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
                        base.Invalidate();
                }
 
-               void OnElementChanged(ElementChangedEventArgs<Image> e)
+               protected virtual void OnElementChanged(ElementChangedEventArgs<Image> e)
                {
                        this.EnsureId();
                        ElementChanged?.Invoke(this, new VisualElementChangedEventArgs(e.OldElement, e.NewElement));
@@ -167,7 +167,8 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
 
                void IImageRendererController.SkipInvalidate() => _skipInvalidate = true;
 
-               AImageView Control => this;
+               protected AImageView Control => this;
+               protected Image Element => _element;
 
                public event EventHandler<VisualElementChangedEventArgs> ElementChanged;
                public event EventHandler<PropertyChangedEventArgs> ElementPropertyChanged;
@@ -182,7 +183,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
                {
                }
 
-               void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+               protected virtual void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
                {
                        ElementPropertyChanged?.Invoke(this, e);
                }
index 7a73d60..89acfcd 100644 (file)
@@ -11,7 +11,7 @@ using AView = Android.Views.View;
 
 namespace Xamarin.Forms.Platform.Android.FastRenderers
 {
-       internal sealed class LabelRenderer : FormsTextView, IVisualElementRenderer, IViewRenderer, ITabStop
+       public class LabelRenderer : FormsTextView, IVisualElementRenderer, IViewRenderer, ITabStop
        {
                int? _defaultLabelFor;
                bool _disposed;
@@ -61,7 +61,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
 
                ViewGroup IVisualElementRenderer.ViewGroup => null;
 
-               Label Element
+               protected Label Element
                {
                        get { return _element; }
                        set
@@ -77,6 +77,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
                                _element?.SendViewInitialized(this);
                        }
                }
+               protected global::Android.Widget.TextView Control => this;
 
                SizeRequest IVisualElementRenderer.GetDesiredSize(int widthConstraint, int heightConstraint)
                {
@@ -202,7 +203,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
                        return _motionEventHelper.HandleMotionEvent(Parent, e);
                }
 
-               void OnElementChanged(ElementChangedEventArgs<Label> e)
+               protected virtual void OnElementChanged(ElementChangedEventArgs<Label> e)
                {
                        ElementChanged?.Invoke(this, new VisualElementChangedEventArgs(e.OldElement, e.NewElement));
 
@@ -237,7 +238,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
                        }
                }
 
-               void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+               protected virtual void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
                {
                        ElementPropertyChanged?.Invoke(this, e);
 
index 887b538..2425192 100644 (file)
@@ -2,6 +2,6 @@ namespace Xamarin.Forms
 {
        internal static class Flags
        {
-               internal const string FastRenderersExperimental = "FastRenderers_Experimental";
+               internal const string UseLegacyRenderers = "UseLegacyRenderers";
        }
 }
\ No newline at end of file