Xamarin.Forms 中的 Droid 自定义选取器渲染器出错

Posted

技术标签:

【中文标题】Xamarin.Forms 中的 Droid 自定义选取器渲染器出错【英文标题】:Error with Droid Custom Picker Renderer in Xamarin.Forms 【发布时间】:2017-11-23 12:09:46 【问题描述】:

我在我的 Xamarin.Forms 应用程序中创建了一个自定义选取器渲染器,在 ios 上它可以正常工作,但在我运行 android 时它会崩溃。

我已经更新了 Visual Studio 2017,并且正在运行 Xamarin.Forms 2.3.4.247。

目标 Android 版本设置为 7.1(6.0 上同样的错误) 最低 Android 版本设置为 4.3

自定义选择器:

使用系统; 使用 Xamarin.Forms; 命名空间 Attest.Combustivel.Infra.Application.Controls 公共类 CustomPicker : 选择器 公共静态只读 BindableProperty FontSizeProperty = BindableProperty.Create(p => p.FontSize, 22); 公共双字体大小 获取返回(双)GetValue(FontSizeProperty); 放 if (this.FontSize != value) 设置值(字体大小属性,值);

自定义 Droid Picker 渲染器 - 出现错误:

使用 Xamarin.Forms; 使用 Xamarin.Forms.Platform.Android; [程序集:ExportRenderer(typeof(Attest.Combustivel.Infra.Application.Controls.CustomPicker), typeof(Attest.Combustivel.Target.Droid.Renderers.DroidCustomPickerRenderer))] 命名空间 Attest.Combustivel.Target.Droid.Renderers 公共类 DroidCustomPickerRenderer : PickerRenderer 受保护的覆盖无效 OnElementChanged(ElementChangedEventArgs e) base.OnElementChanged(e); //如果(控制==空) // // 返回; // //var customPicker = e.NewElement as CustomPicker; //if (customPicker != null) // // Control.TextSize = Convert.ToSingle(customPicker.FontSize); //

自定义 IOS 选择器渲染器 - 工作正常:

使用 Attest.Combustivel.Infra.Application.Controls; 使用核心图形; 使用系统; 使用 UIKit; 使用 Xamarin.Forms; 使用 Xamarin.Forms.Platform.iOS; [程序集:ExportRenderer(typeof(Attest.Combustivel.Infra.Application.Controls.CustomPicker), typeof(Attest.Combustivel.Target.Droid.Renderers.IOSCustomPickerRenderer))] 命名空间 Attest.Combustivel.Target.Droid.Renderers 公共类 IOSCustomPickerRenderer : PickerRenderer 受保护的覆盖无效 OnElementChanged(ElementChangedEventArgs e) base.OnElementChanged(e); 如果(控制 == 空) 返回; var customPicker = e.NewElement as CustomPicker; // 字体大小 if (customPicker?.FontSize != null) Control.Font = UIFont.FromName(".SF UI Text", Convert.ToSingle(customPicker.FontSize));

错误:

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)

【问题讨论】:

我看到您在“Attest.Combustivel.Target.Droid.Renderers”处使用相同的命名空间,即使在 iOS 应用程序中也是如此。这是故意的吗? 尝试清理和重建你的代码。异常表明您正在尝试注册 2 个我在您的代码中看不到的渲染器:TableViewRenderer 和 DroidCustomTableViewRenderer,然后当它尝试将您的 CustomPicker 转换为 TableView 时它崩溃。它究竟在哪里崩溃?您可以设置断点并找到该行,否则它会在到达 OnElementChanged 之前崩溃? 非常感谢!这是一个复制粘贴问题,我试图将两个不同的渲染器注册到相同的自定义类型。问题解决了。 请发布答案,以便我标记为解决方案 不确定解决方案是什么? :-) 你有没有在代码中提到的表格渲染器吗? 【参考方案1】:

尝试将 OnElementChanged 的覆盖方法更改为如下所示:

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);
    

【讨论】:

【参考方案2】:

我们从异常中发现同一类型的渲染器更多。

【讨论】:

是的,我有其他渲染,我试图用相同的自定义类型 (CustomPicker) 注册其中的两个。谢谢,是复制粘贴问题

以上是关于Xamarin.Forms 中的 Droid 自定义选取器渲染器出错的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin.Forms 条目 - 自定义行为和 MVVM

Xamarin.Forms 中的 MVVMLight 的 EventToCommand

添加对 Xamarin.Forms 的项目引用

Xamarin Forms Android Build 中的 AccessibilityServiceInfoCompat 错误

使用 Xamarin Forms 在 UWP 中自定义进度条颜色

如何在 xamarin 中为 android 添加工具栏,因为 ToolbarItem 不适用于 .droid?