ContentPage中的ViewGroup-ExportRenderer问题Xamarin

时间:2018-11-06 14:33:50

标签: xamarin xamarin.forms xamarin.android

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

Xamarin Forms Custom Renderer for Android not displaying

Adding an "Android.Views.ViewGroup" to a Xamarin XAML page

和其他人。

但是我无法使其正常运行。

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

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

在我的MainActivity.OnCreate中,我有:

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时,还将按照MainPage.xaml和OnElementChanged向其中添加rlMainContainer,但是没有要求MyCustomViewRenderer内部的任何内容(没有断点命中)。

我在做什么错了?

3 个答案:

答案 0 :(得分:1)

我只是将您的代码插入一个新项目,只要我明确要使用哪个RelativeLayout,它就可以正常工作。 Xamarin.Forms.RelativeLayout和Android.Widget.Relative布局可能有2种。我假设您想要后者,但我不认为它是完全合格的,并且由于我假设您对Xamarin.Forms(ExportRenderer属性需要)和Android.Widget(RelativeLayout需要)都使用了语句,因此不清楚您在所有地方都使用了正确的RelativeLayout。

还有一个问题是您使用的是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);
        }
    }
}

答案 1 :(得分:0)

您为什么要渲染本机Android RelativeLayout? Xamarin.Forms中有内置选项。看看这个documentation

答案 2 :(得分:0)

经过大量文件比较(我的项目和Microsoft示例),我发现此问题与

有关

MainPage = new NavigationPage(new MainPage());

要解决此问题,我刚刚移除了NavigationPage包装器。

MainPage = new MainPage();

尚不知道为什么会这样,但是如果有人知道,也请编辑我的回答并附上说明。

编辑:渲染器也可以与NavigationPage一起使用,但仅在OnCreate方法完成执行之后。