Allow Custom Android MapRenderers to override the default MapView options (#285)
authorMarcus Lum <marcusl@gmail.com>
Tue, 30 Aug 2016 17:37:07 +0000 (13:37 -0400)
committerJason Smith <jason.smith@xamarin.com>
Tue, 30 Aug 2016 17:37:07 +0000 (10:37 -0700)
* Allow Custom Android MapRenderers to override the default MapView options

* Larger effort to use CreateNativeControl () everywhere instead of just in the Android AppCompat renderers.

24 files changed:
Xamarin.Forms.ControlGallery.Android/CustomRenderers.cs
Xamarin.Forms.Maps.Android/MapRenderer.cs
Xamarin.Forms.Platform.Android/AppCompat/ViewRenderer.cs
Xamarin.Forms.Platform.Android/NativeViewWrapperRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/ActivityIndicatorRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/ButtonRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/DatePickerRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/EditorRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/EntryRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/ImageRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/LabelRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/ListViewRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/NavigationMenuRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/OpenGLViewRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/PickerRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/ProgressBarRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/SearchBarRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/SliderRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/StepperRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/SwitchRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/TableViewRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/TimePickerRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/WebViewRenderer.cs
Xamarin.Forms.Platform.Android/ViewRenderer.cs

index 1faa7a9..7f86a85 100644 (file)
@@ -97,13 +97,18 @@ namespace Xamarin.Forms.ControlGallery.Android
                {
                }
 
+               protected override global::Android.Widget.ListView CreateNativeControl()
+               {
+                       return new global::Android.Widget.ListView(Forms.Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<NativeListView> e)
                {
                        base.OnElementChanged(e);
 
                        if (Control == null)
                        {
-                               SetNativeControl(new global::Android.Widget.ListView(Forms.Context));
+                               SetNativeControl(CreateNativeControl());
                        }
 
                        if (e.OldElement != null)
@@ -266,13 +271,18 @@ namespace Xamarin.Forms.ControlGallery.Android
                {
                }
 
+               protected override global::Android.Widget.ListView CreateNativeControl()
+               {
+                       return new global::Android.Widget.ListView(Forms.Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<NativeListView2> e)
                {
                        base.OnElementChanged(e);
 
                        if (Control == null)
                        {
-                               SetNativeControl(new global::Android.Widget.ListView(Forms.Context));
+                               SetNativeControl(CreateNativeControl());
                        }
 
                        if (e.OldElement != null)
@@ -406,7 +416,7 @@ namespace Xamarin.Forms.ControlGallery.Android
                        return view;
                }
        }
-       public class CustomContentRenderer : ViewRenderer
+       public abstract class CustomContentRenderer : ViewRenderer
        {
        }
 
@@ -435,11 +445,16 @@ namespace Xamarin.Forms.ControlGallery.Android
 
        public class CustomButtonRenderer : ButtonRenderer
        {
+               protected override AButton CreateNativeControl()
+               {
+                       return new CustomNativeButton(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
                {
                        if (Control == null)
                        {
-                               CustomNativeButton b = new CustomNativeButton(Context);
+                               CustomNativeButton b = (CustomNativeButton)CreateNativeControl();
                                SetNativeControl(b);
                        }
 
index a0a3bbc..29270c0 100644 (file)
@@ -15,7 +15,7 @@ using System.Collections;
 
 namespace Xamarin.Forms.Maps.Android
 {
-       public class MapRenderer : ViewRenderer, 
+       public class MapRenderer : ViewRenderer<Map,MapView>
                GoogleMap.IOnCameraChangeListener 
        {
                public MapRenderer ()
@@ -41,19 +41,24 @@ namespace Xamarin.Forms.Maps.Android
                        return new SizeRequest (new Size (Context.ToPixels (40), Context.ToPixels (40)));
                }
 
-               protected override void OnElementChanged (ElementChangedEventArgs<View> e)
+               protected override MapView CreateNativeControl()
+               {
+                       return new MapView(Context);
+               }
+
+               protected override void OnElementChanged (ElementChangedEventArgs<Map> e)
                {
                        base.OnElementChanged (e);
 
                        var oldMapView = (MapView)Control;
 
-                       var mapView = new MapView (Context);
+                       var mapView = CreateNativeControl();
                        mapView.OnCreate (s_bundle);
                        mapView.OnResume ();
                        SetNativeControl (mapView);
 
                        if (e.OldElement != null) {
-                               var oldMapModel = (Map) e.OldElement;
+                               var oldMapModel = e.OldElement;
                                ((ObservableCollection<Pin>)oldMapModel.Pins).CollectionChanged -= OnCollectionChanged;
 
                                MessagingCenter.Unsubscribe<Map, MapSpan> (this, MoveMessageName);
index 3c86921..85ff398 100644 (file)
@@ -2,6 +2,5 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
 {
        public abstract class ViewRenderer<TView, TControl> : Android.ViewRenderer<TView, TControl> where TView : View where TControl : global::Android.Views.View
        {
-               protected abstract TControl CreateNativeControl();
        }
 }
\ No newline at end of file
index 2036e4b..d2f2397 100644 (file)
@@ -17,6 +17,12 @@ namespace Xamarin.Forms.Platform.Android
                        return result ?? base.GetDesiredSize(widthConstraint, heightConstraint);
                }
 
+               // not called by the view wrapper renderer
+               protected override global::Android.Views.View CreateNativeControl()
+               {
+                       return new global::Android.Views.View(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<NativeViewWrapper> e)
                {
                        base.OnElementChanged(e);
index 696e6f6..f536b47 100644 (file)
@@ -13,6 +13,11 @@ namespace Xamarin.Forms.Platform.Android
                        AutoPackage = false;
                }
 
+               protected override AProgressBar CreateNativeControl()
+               {
+                       return new AProgressBar(Context) { Indeterminate = true };
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<ActivityIndicator> e)
                {
                        base.OnElementChanged(e);
@@ -20,7 +25,7 @@ namespace Xamarin.Forms.Platform.Android
                        AProgressBar progressBar = Control;
                        if (progressBar == null)
                        {
-                               progressBar = new AProgressBar(Context) { Indeterminate = true };
+                               progressBar = CreateNativeControl();
                                SetNativeControl(progressBar);
                        }
 
index 5de429a..4f384b3 100644 (file)
@@ -80,6 +80,11 @@ namespace Xamarin.Forms.Platform.Android
                        base.Dispose(disposing);
                }
 
+               protected override AButton CreateNativeControl()
+               {
+                       return new AButton(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
                {
                        base.OnElementChanged(e);
@@ -89,7 +94,7 @@ namespace Xamarin.Forms.Platform.Android
                                AButton button = Control;
                                if (button == null)
                                {
-                                       button = new AButton(Context);
+                                       button = CreateNativeControl();
                                        button.SetOnClickListener(ButtonClickListener.Instance.Value);
                                        button.Tag = this;
                                        SetNativeControl(button);
index 73e5183..96028c3 100644 (file)
@@ -42,13 +42,18 @@ namespace Xamarin.Forms.Platform.Android
                        base.Dispose(disposing);
                }
 
+               protected override EditText CreateNativeControl()
+               {
+                       return new EditText(Context) { Focusable = false, Clickable = true, Tag = this };
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
                {
                        base.OnElementChanged(e);
 
                        if (e.OldElement == null)
                        {
-                               var textField = new EditText(Context) { Focusable = false, Clickable = true, Tag = this };
+                               var textField = CreateNativeControl();
 
                                textField.SetOnClickListener(TextFieldClickHandler.Instance);
                                SetNativeControl(textField);
index 14078ab..c9b596b 100644 (file)
@@ -33,6 +33,11 @@ namespace Xamarin.Forms.Platform.Android
                                ((IElementController)Element).SetValueFromRenderer(Editor.TextProperty, s.ToString());
                }
 
+               protected override EditorEditText CreateNativeControl()
+               {
+                       return new EditorEditText(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
                {
                        base.OnElementChanged(e);
@@ -42,7 +47,7 @@ namespace Xamarin.Forms.Platform.Android
                        EditorEditText edit = Control;
                        if (edit == null)
                        {
-                               edit = new EditorEditText(Context);
+                               edit = CreateNativeControl();
 
                                SetNativeControl(edit);
                                edit.AddTextChangedListener(this);
index c1b0b5e..c1c24a8 100644 (file)
@@ -49,6 +49,11 @@ namespace Xamarin.Forms.Platform.Android
                        ((IElementController)Element).SetValueFromRenderer(Entry.TextProperty, s.ToString());
                }
 
+               protected override EntryEditText CreateNativeControl()
+               {
+                       return new EntryEditText(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
                {
                        base.OnElementChanged(e);
@@ -57,7 +62,7 @@ namespace Xamarin.Forms.Platform.Android
 
                        if (e.OldElement == null)
                        {
-                               _textView = new EntryEditText(Context);
+                               _textView = CreateNativeControl();
                                _textView.ImeOptions = ImeAction.Done;
                                _textView.AddTextChangedListener(this);
                                _textView.SetOnEditorActionListener(this);
index 1f8a776..e3c6829 100644 (file)
@@ -28,13 +28,18 @@ namespace Xamarin.Forms.Platform.Android
                        base.Dispose(disposing);
                }
 
+               protected override AImageView CreateNativeControl()
+               {
+                       return new FormsImageView(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
                {
                        base.OnElementChanged(e);
 
                        if (e.OldElement == null)
                        {
-                               var view = new FormsImageView(Context);
+                               var view = CreateNativeControl();
                                SetNativeControl(view);
                        }
 
index 0be9740..c544a23 100644 (file)
@@ -67,12 +67,17 @@ namespace Xamarin.Forms.Platform.Android
                        return result;
                }
 
+               protected override TextView CreateNativeControl()
+               {
+                       return new FormsTextView(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
                {
                        base.OnElementChanged(e);
                        if (_view == null)
                        {
-                               _view = new FormsTextView(Context);
+                               _view = (FormsTextView)CreateNativeControl();
                                _labelTextColorDefault = _view.TextColors;
                                SetNativeControl(_view);
                        }
index f835192..1054e1e 100644 (file)
@@ -95,6 +95,11 @@ namespace Xamarin.Forms.Platform.Android
                        _adapter.IsAttachedToWindow = _isAttached;
                }
 
+               protected override AListView CreateNativeControl()
+               {
+                       return new AListView(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
                {
                        base.OnElementChanged(e);
@@ -116,7 +121,7 @@ namespace Xamarin.Forms.Platform.Android
                                if (nativeListView == null)
                                {
                                        var ctx = Context;
-                                       nativeListView = new AListView(ctx);
+                                       nativeListView = CreateNativeControl();
                                        _refresh = new SwipeRefreshLayout(ctx);
                                        _refresh.SetOnRefreshListener(this);
                                        _refresh.AddView(nativeListView, LayoutParams.MatchParent);
index 92a6511..c7e45ad 100644 (file)
@@ -26,13 +26,18 @@ namespace Xamarin.Forms.Platform.Android
                        get { return Element as NavigationMenu; }
                }
 
+               protected override AView CreateNativeControl()
+               {
+                       return new GridView(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<View> e)
                {
                        base.OnElementChanged(e);
 
                        if (e.OldElement == null)
                        {
-                               var grid = new GridView(Context);
+                               var grid = (GridView)CreateNativeControl();
                                grid.SetVerticalSpacing(20);
 
                                SetNativeControl(grid);
index 0bddfb5..a97a208 100644 (file)
@@ -28,6 +28,11 @@ namespace Xamarin.Forms.Platform.Android
                        base.Dispose(disposing);
                }
 
+               protected override GLSurfaceView CreateNativeControl()
+               {
+                       return new GLSurfaceView(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<OpenGLView> e)
                {
                        base.OnElementChanged(e);
@@ -40,7 +45,7 @@ namespace Xamarin.Forms.Platform.Android
                                GLSurfaceView surfaceView = Control;
                                if (surfaceView == null)
                                {
-                                       surfaceView = new GLSurfaceView(Context);
+                                       surfaceView = CreateNativeControl();
                                        surfaceView.SetEGLContextClientVersion(2);
                                        SetNativeControl(surfaceView);
                                }
index f2abe9d..b6d8171 100644 (file)
@@ -36,6 +36,11 @@ namespace Xamarin.Forms.Platform.Android
                        base.Dispose(disposing);
                }
 
+               protected override EditText CreateNativeControl()
+               {
+                       return new EditText(Context) { Focusable = false, Clickable = true, Tag = this };
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
                {
                        if (e.OldElement != null)
@@ -46,7 +51,7 @@ namespace Xamarin.Forms.Platform.Android
                                ((ObservableList<string>)e.NewElement.Items).CollectionChanged += RowsCollectionChanged;
                                if (Control == null)
                                {
-                                       var textField = new EditText(Context) { Focusable = false, Clickable = true, Tag = this };
+                                       var textField = CreateNativeControl();
                                        textField.SetOnClickListener(PickerListener.Instance);
                                        _textColorSwitcher = new TextColorSwitcher(textField.TextColors);
                                        SetNativeControl(textField);
index 865732f..63316a2 100644 (file)
@@ -10,13 +10,18 @@ namespace Xamarin.Forms.Platform.Android
                        AutoPackage = false;
                }
 
+               protected override AProgressBar CreateNativeControl()
+               {
+                       return new AProgressBar(Context, null, global::Android.Resource.Attribute.ProgressBarStyleHorizontal) { Indeterminate = false, Max = 10000 };
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<ProgressBar> e)
                {
                        base.OnElementChanged(e);
 
                        if (e.OldElement == null)
                        {
-                               var progressBar = new AProgressBar(Context, null, global::Android.Resource.Attribute.ProgressBarStyleHorizontal) { Indeterminate = false, Max = 10000 };
+                               var progressBar = CreateNativeControl();
 
                                SetNativeControl(progressBar);
                        }
index 5e49895..468710c 100644 (file)
@@ -1,3 +1,4 @@
+using System;
 using System.ComponentModel;
 using System.Linq;
 using Android.Content.Res;
@@ -36,6 +37,11 @@ namespace Xamarin.Forms.Platform.Android
                        return true;
                }
 
+               protected override SearchView CreateNativeControl()
+               {
+                       return new SearchView(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
                {
                        base.OnElementChanged(e);
@@ -46,7 +52,7 @@ namespace Xamarin.Forms.Platform.Android
 
                        if (searchView == null)
                        {
-                               searchView = new SearchView(Context);
+                               searchView = CreateNativeControl();
                                searchView.SetIconifiedByDefault(false);
                                searchView.Iconified = false;
                                SetNativeControl(searchView);
index dbe1887..5df5bf3 100644 (file)
@@ -34,13 +34,18 @@ namespace Xamarin.Forms.Platform.Android
                {
                }
 
+               protected override SeekBar CreateNativeControl()
+               {
+                       return new FormsSeekBar(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<Slider> e)
                {
                        base.OnElementChanged(e);
 
                        if (e.OldElement == null)
                        {
-                               var seekBar = new FormsSeekBar(Context);
+                               var seekBar = CreateNativeControl();
                                SetNativeControl(seekBar);
 
                                seekBar.Max = 1000;
index 70eed60..88b5fd7 100644 (file)
@@ -16,6 +16,11 @@ namespace Xamarin.Forms.Platform.Android
                        AutoPackage = false;
                }
 
+               protected override LinearLayout CreateNativeControl()
+               {
+                       return new LinearLayout(Context) { Orientation = Orientation.Horizontal };
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
                {
                        base.OnElementChanged(e);
@@ -31,7 +36,7 @@ namespace Xamarin.Forms.Platform.Android
                                _upButton.SetOnClickListener(StepperListener.Instance);
                                _upButton.SetHeight((int)Context.ToPixels(10.0));
 
-                               var layout = new LinearLayout(Context) { Orientation = Orientation.Horizontal };
+                               var layout = CreateNativeControl();
 
                                layout.AddView(_downButton);
                                layout.AddView(_upButton);
index 39916b5..2c0b014 100644 (file)
@@ -47,6 +47,11 @@ namespace Xamarin.Forms.Platform.Android
                        base.Dispose(disposing);
                }
 
+               protected override ASwitch CreateNativeControl()
+               {
+                       return new ASwitch(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
                {
                        base.OnElementChanged(e);
@@ -58,7 +63,7 @@ namespace Xamarin.Forms.Platform.Android
                        {
                                if (Control == null)
                                {
-                                       var aswitch = new ASwitch(Context);
+                                       var aswitch = CreateNativeControl();
                                        aswitch.SetOnCheckedChangeListener(this);
                                        SetNativeControl(aswitch);
                                }
index e4017a7..2ac8efa 100644 (file)
@@ -21,6 +21,11 @@ namespace Xamarin.Forms.Platform.Android
                        return new Size(40, 40);
                }
 
+               protected override AListView CreateNativeControl()
+               {
+                       return new AListView(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
                {
                        base.OnElementChanged(e);
@@ -28,7 +33,7 @@ namespace Xamarin.Forms.Platform.Android
                        AListView listView = Control;
                        if (listView == null)
                        {
-                               listView = new AListView(Context);
+                               listView = CreateNativeControl();
                                SetNativeControl(listView);
                        }
 
index 2b33acc..2bd60a7 100644 (file)
@@ -34,13 +34,18 @@ namespace Xamarin.Forms.Platform.Android
                        _dialog = null;
                }
 
+               protected override EditText CreateNativeControl()
+               {
+                       return new EditText(Context) { Focusable = false, Clickable = true, Tag = this };
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<TimePicker> e)
                {
                        base.OnElementChanged(e);
 
                        if (e.OldElement == null)
                        {
-                               var textField = new EditText(Context) { Focusable = false, Clickable = true, Tag = this };
+                               var textField = CreateNativeControl();
 
                                textField.SetOnClickListener(TimePickerListener.Instance);
                                SetNativeControl(textField);
index 24a5af5..bd5b805 100644 (file)
@@ -56,13 +56,18 @@ namespace Xamarin.Forms.Platform.Android
                        return new Size(Context.ToPixels(40), Context.ToPixels(40));
                }
 
+               protected override AWebView CreateNativeControl()
+               {
+                       return new AWebView(Context);
+               }
+
                protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
                {
                        base.OnElementChanged(e);
 
                        if (Control == null)
                        {
-                               var webView = new AWebView(Context);
+                               var webView = CreateNativeControl();
 #pragma warning disable 618 // This can probably be replaced with LinearLayout(LayoutParams.MatchParent, LayoutParams.MatchParent); just need to test that theory
                                webView.LayoutParameters = new global::Android.Widget.AbsoluteLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent, 0, 0);
 #pragma warning restore 618
index 63fef49..f285d6d 100644 (file)
@@ -13,6 +13,8 @@ namespace Xamarin.Forms.Platform.Android
 
        public abstract class ViewRenderer<TView, TNativeView> : VisualElementRenderer<TView>, AView.IOnFocusChangeListener where TView : View where TNativeView : AView
        {
+               protected abstract TNativeView CreateNativeControl();
+
                ViewGroup _container;
 
                bool _disposed;