ViewGroup in ContentPage - ExportRenderer issue Xamarin



我想在ContentPage中添加一个Android.Widget.RelativeLayout。为此,我遵循了多个在线示例:

Xamarin窗体自定义渲染器Android不显示

添加一个";Android.Views.ViewGroup";到Xamarin XAML页面

以及其他。

但我不能让它工作。

在我的共享项目中,我有:

namespace SharedProject
{
public partial class App : Application
{
public App ()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
....
}

空间

namespace SharedProject
{
public class MyCustomViewControl : View
{
public MyCustomViewControl()
{
}
}
}

以及正在渲染的MainPage.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:SharedProject="clr-namespace:SharedProject;assembly=SharedProject"
x:Class="SharedProject.MainPage">
<ContentPage.Content>
<StackLayout>
<SharedProject:MyCustomViewControl
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>

以及在MonoAndroid项目中:

[assembly: ExportRenderer(typeof(MyCustomViewControl), typeof(MyCustomViewRenderer))]
namespace SharedProject.Mobile.Droid
{
public class MyCustomViewRenderer : ViewRenderer<MyCustomViewControl, RelativeLayout>
{
public MyCustomViewRenderer(Context context) : base(context)
{
}
private Android.Widget.RelativeLayout rlMainContainer;
protected override void OnElementChanged(ElementChangedEventArgs<MyCustomViewControl> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || Element == null)
{
return;
}
rlMainContainer = new RelativeLayout(Context);
rlMainContainer.SetMinimumHeight(50);
rlMainContainer.SetMinimumWidth(100);
rlMainContainer.LayoutParameters = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MatchParent, RelativeLayout.LayoutParams.MatchParent);
if (Control == null)
SetNativeControl(rlMainContainer);
MainActivity.instance.setActiveReader(Control);
}
}
}

在我的主要活动中。创建我有:

protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

instance = this;
LoadApplication(new App());

我原以为在渲染MainPage时,rlMainContainer也会按照MainPage.xaml和OnElementChanged添加到其中,但MyCustomViewRenderer内部没有任何请求(没有断点命中(。

我做错了什么?

我刚刚将您的代码插入到一个新项目中,只要我明确表示要使用哪个RelativeLayout,它就可以正常工作。有两种可能,Xamarin.Forms.RelativeLayout和Android.Widget.Relative布局。我想你想要后者,但我不认为它是完全限定的,而且由于我认为你同时使用了Xamarin.Forms(ExportRenderer属性所需(和Android.Widget(RelativeLayout所需(的语句,所以不清楚你是否在所有地方都使用了正确的RelativeLLayout。

还有一个问题是,您使用的是Xamarin.Forms.Platform.Android.AppCompat.ViewRenderer还是Xamarin.Forms.Platform.Android.ViewRenderer。大多数使用AppCompat作为默认Xam。Forms模板使用FormsAppCompatActivity。因此,假设您使用的是AppCompat,以下自定义渲染器的完整源代码(根据需要提供完整的类型限定(正在我的端上运行:

using System;
using Android.Content;
using TestRelLayout;
using TestRelLayout.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(MyCustomViewControl), typeof(MyCustomViewRenderer))]
namespace TestRelLayout.Droid
{
public class MyCustomViewRenderer : Xamarin.Forms.Platform.Android.AppCompat.ViewRenderer<MyCustomViewControl, Android.Widget.RelativeLayout>
{
public MyCustomViewRenderer(Context context) : base(context)
{
}
private Android.Widget.RelativeLayout rlMainContainer;

protected override void OnElementChanged(ElementChangedEventArgs<MyCustomViewControl> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || Element == null)
{
return;
}
rlMainContainer = new Android.Widget.RelativeLayout(Context);
rlMainContainer.SetMinimumHeight(50);
rlMainContainer.SetMinimumWidth(100);
rlMainContainer.LayoutParameters = new Android.Widget.RelativeLayout.LayoutParams(Android.Widget.RelativeLayout.LayoutParams.MatchParent, Android.Widget.RelativeLayout.LayoutParams.MatchParent);
// set the background color to make it easy to see if renderer is working               
rlMainContainer.SetBackgroundColor(
Android.Graphics.Color.Aquamarine);
if (Control == null)
SetNativeControl(rlMainContainer);
// did not bother to set this up in my MainActivity
//MainActivity.instance.setActiveReader(Control);
}
}
}

为什么要渲染原生Android RelativeLayout?Xamarin.Forms中有内置选项。查看此文档

经过大量文件比较(我的项目和微软的示例项目(,我发现问题与有关

MainPage = new NavigationPage(new MainPage());

为了解决这个问题,我刚刚删除了NavigationPage包装。

MainPage = new MainPage();

还不知道为什么会发生这种情况,但如果有人知道,请编辑我的回答并做出解释。

编辑:Renderer也适用于NavigationPage,但只有在OnCreate方法完成执行之后。

最新更新