0
votes

I've created a Custom Picker Renderer in my Xamarin.Forms application, on IOS it works fine but it crashes when I run Android.

I've already updated Visual Studio 2017 and I'am running Xamarin.Forms 2.3.4.247.

Target Android Version is set to 7.1 (same error on 6.0) Minimum Android Version is set to 4.3

Custom Picker:


    using System;
    using Xamarin.Forms;

    namespace Attest.Combustivel.Infra.Application.Controls
    {
        public class CustomPicker : Picker
        {
            public static readonly BindableProperty FontSizeProperty = BindableProperty.Create(p => p.FontSize, 22);

            public Double FontSize
            {
                get { return (double)GetValue(FontSizeProperty); }
                set
                {
                    if (this.FontSize != value)
                    {
                        SetValue(FontSizeProperty, value);
                    }
                }
            }
        }
    }

Custom Droid Picker Renderer - With Error:


    using Xamarin.Forms;
    using Xamarin.Forms.Platform.Android;

    [assembly: ExportRenderer(typeof(Attest.Combustivel.Infra.Application.Controls.CustomPicker), typeof(Attest.Combustivel.Target.Droid.Renderers.DroidCustomPickerRenderer))]
    namespace Attest.Combustivel.Target.Droid.Renderers
    {
        public class DroidCustomPickerRenderer : PickerRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs e)
            {
                base.OnElementChanged(e);

                //if (Control == null)
                //{
                //    return;
                //}

                //var customPicker = e.NewElement as CustomPicker;

                //if (customPicker != null)
                //{
                //    Control.TextSize = Convert.ToSingle(customPicker.FontSize);
                //}
            }
        }
    }

Custom IOS Picker Renderer - Works Fine:


    using Attest.Combustivel.Infra.Application.Controls;
    using CoreGraphics;
    using System;
    using UIKit;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.iOS;

    [assembly: ExportRenderer(typeof(Attest.Combustivel.Infra.Application.Controls.CustomPicker), typeof(Attest.Combustivel.Target.Droid.Renderers.IOSCustomPickerRenderer))]
    namespace Attest.Combustivel.Target.Droid.Renderers
    {
        public class IOSCustomPickerRenderer : PickerRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs e)
            {
                base.OnElementChanged(e);

                if (Control == null)
                {
                    return;
                }

                var customPicker = e.NewElement as CustomPicker;

                // FontSize
                if (customPicker?.FontSize != null)
                {
                    Control.Font = UIFont.FromName(".SF UI Text", Convert.ToSingle(customPicker.FontSize));
                }
            }
        }
    }

The Error:

06-20 16:15:02.261 W/art     ( 7541): JNI RegisterNativeMethods: attempt to register 0 native methods for md5b60ffeb829f638581ab2bb9b1a7f4f3f.TableViewRenderer
06-20 16:15:02.261 W/art     ( 7541): JNI RegisterNativeMethods: attempt to register 0 native methods for md5718175f0eae2ce5b6bb8ba01f33420ae.DroidCustomTableViewRenderer
06-20 16:15:04.911 D/Mono    ( 7541): DllImport attempting to load: '/system/lib/liblog.so'.
06-20 16:15:04.911 D/Mono    ( 7541): DllImport loaded library '/system/lib/liblog.so'.
06-20 16:15:04.911 D/Mono    ( 7541): DllImport searching in: '/system/lib/liblog.so' ('/system/lib/liblog.so').
06-20 16:15:04.911 D/Mono    ( 7541): Searching for '__android_log_print'.
06-20 16:15:04.911 D/Mono    ( 7541): Probing '__android_log_print'.
06-20 16:15:04.911 D/Mono    ( 7541): Found as '__android_log_print'.
06-20 16:15:04.921 I/MonoDroid( 7541): UNHANDLED EXCEPTION:
06-20 16:15:04.981 I/MonoDroid( 7541): System.ArgumentException: element is not of type Xamarin.Forms.TableView
06-20 16:15:04.981 I/MonoDroid( 7541): Parameter name: element
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.Android.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00008] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:135 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x0001f] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\Platform.cs:289 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementPackager.AddChild (Xamarin.Forms.VisualElement view, Xamarin.Forms.Platform.Android.IVisualElementRenderer oldRenderer, Xamarin.Forms.Platform.Android.RendererPool pool, System.Boolean sameChildren) [0x00023] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:84 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementPackager.SetElement (Xamarin.Forms.VisualElement oldElement, Xamarin.Forms.VisualElement newElement) [0x00104] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:217 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementPackager.Load () [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:68 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].SetPackager (Xamarin.Forms.Platform.Android.VisualElementPackager packager) [0x00007] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:335 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x00111] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:199 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.Android.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00027] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:137 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x0001f] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\Platform.cs:289 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementPackager.AddChild (Xamarin.Forms.VisualElement view, Xamarin.Forms.Platform.Android.IVisualElementRenderer oldRenderer, Xamarin.Forms.Platform.Android.RendererPool pool, System.Boolean sameChildren) [0x00023] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:84 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementPackager.SetElement (Xamarin.Forms.VisualElement oldElement, Xamarin.Forms.VisualElement newElement) [0x00104] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:217 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementPackager.Load () [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:68 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].SetPackager (Xamarin.Forms.Platform.Android.VisualElementPackager packager) [0x00007] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:335 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x00111] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:199 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.Android.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00027] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:137 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x0001f] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\Platform.cs:289 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementPackager.AddChild (Xamarin.Forms.VisualElement view, Xamarin.Forms.Platform.Android.IVisualElementRenderer oldRenderer, Xamarin.Forms.Platform.Android.RendererPool pool, System.Boolean sameChildren) [0x00023] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:84 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementPackager.SetElement (Xamarin.Forms.VisualElement oldElement, Xamarin.Forms.VisualElement newElement) [0x00104] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:217 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementPackager.Load () [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:68 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].SetPackager (Xamarin.Forms.Platform.Android.VisualElementPackager packager) [0x00007] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:335 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x00111] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:199 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.Android.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00027] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:137 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.Platform.CreateRenderer (Xamarin.Forms.VisualElement element, Android.Support.V4.App.FragmentManager fragmentManager) [0x00031] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\Platform.cs:325 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Xamarin.Forms.Platform.Android.AppCompat.FragmentContainer.OnCreateView (Android.Views.LayoutInflater inflater, Android.Views.ViewGroup container, Android.OS.Bundle savedInstanceState) [0x00008] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\AppCompat\FragmentContainer.cs:67 
06-20 16:15:04.981 I/MonoDroid( 7541):   at Android.Support.V4.App.Fragment.n_OnCreateView_Landroid_view_LayoutInflater_Landroid_view_ViewGroup_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_inflater, System.IntPtr native_container, System.IntPtr native_savedInstanceState) [0x00022] in <27c17fe440cf491ba8255bcefade6e02>:0 
06-20 16:15:04.981 I/MonoDroid( 7541):   at (wrapper dynamic-method) System.Object:63a8a4b1-f4fe-4a75-89d0-ed93d90f2880 (intptr,intptr,intptr,intptr,intptr)

Visual Studio 2017 and Xamarin.Forms versions Android target and minimum versions

2
I see you are using the same namespaces everywhere "Attest.Combustivel.Target.Droid.Renderers" even in iOS app. Is that intentional?Yuri S
Try to clean and rebuild your code. Exception shows that you are trying to register 2 renderers which I don't see in your code: TableViewRenderer and DroidCustomTableViewRenderer and then it crashes when it tries to cast your CustomPicker to TableView. Where exactly it crashes? Can you put breakpoint and find the line or it crashes before it reaches OnElementChanged?Yuri S
Thank you so much! It was an copy paste problem, I was trying to register two different renderers to the same custom type. The problem was solved.Luis Rodrigues
Please post an answer so I can mark as the solutionLuis Rodrigues
Not sure what the solution was? :-) Did you have table renderers which you didn't mention in code?Yuri S

2 Answers

2
votes

We figured out from exception that there were more renderers for the same type.

1
votes

Try changing your override method for OnElementChanged to something like this:

protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Picker> e)
{
    base.OnElementChanged(e);

    if (Control == null)
    {
        return;
    }

    var customPicker = e.NewElement as CustomPicker;

    if (customPicker != null)
    {
        Control.TextSize = Convert.ToSingle(customPicker.FontSize);
    }
}