9
votes

I need some help with adding an Android.Views.ViewGroup to a XAML page.

I have a Xamarin project with a solution structure that looks like this:

  • App1
    • /ViewModels
      • /MyPageViewModel.cs
    • /Views
      • /MyPageView.xaml
        • /MyPageView.xaml.cs
  • App1.Android
    • /MainActivity.cs
    • /MainApplication.cs
  • App1.iOS
  • MyAndroidBindingProject
    • /Jars
      • /customViewGroup.aar

Note the customViewGroup.aar that I've added to the solution using a Xamarin Android Binding Library.

The AAR file contains an Android.Views.ViewGroup class that I'd like to show on MyPage.xaml but I have no clue how to do it. I can't seem to find a guide or code sample that fits this exact use case (nor can I find one that involves adding a simple Android.Views.View to a Xamarin XAML page).

I've found examples of adding an Android.Views.ViewGroup to a native Android application (using Java and XML) but nothing that shows how to add it to a Xamarin XAML page.

Please help!


I'm including some source code so you can see what I've tried:

MyPage.xaml

<ContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="App1.Views.MyPage"
    xmlns:vm="clr-namespace:App1.ViewModels;"
    xmlns:androidWidget="clr-namespace:Com.CustomAAR;assembly=Com.CustomAAR;targetPlatform=Android"
    xmlns:formsAndroid="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.Platform.Android;targetPlatform=Android"
    Title="{Binding Title}">
    <ContentPage.Content>
        <ContentView x:Name="contentViewParent">
            <androidWidget:MyCustomViewGroup x:Arguments="{x:Static formsandroid:Forms.Context}"> 
            </androidWidget:MyCustomViewGroup>
        </ContentView>
        <!--<ContentView 
            IsVisible="True"
            IsEnabled="True"
            BindingContext="{Binding MyCustomViewGroup}">
        </ContentView>-->
    </ContentPage.Content>
</ContentPage>

MyPage.xaml.cs

public partial class MyPage : ContentPage
{
    MyCustomViewGroupModel viewModel;

    public MyPage()
    {
        InitializeComponent ();
    }

    public MyPage(MyCustomViewGroupModel viewModel)
    {
        InitializeComponent();

#if __ANDROID__
        NativeViewWrapper wrapper = (NativeViewWrapper)contentViewParent.Content;
        MyCustomViewGroup myCustomViewGroup = (MyCustomViewGroup)wrapper.NativeView;

        //myCustomViewGroup = new MyCustomViewGroup(Android.App.Application.Context);

        myCustomViewGroup.SomeAction("");
#endif

        BindingContext = this.viewModel = viewModel;
    }
}
1
Trying that now, thank you!Omar Himada
Hmmm no dice. I've edited my question to include the code I'm using. The page just appears blank.Omar Himada
Make sure there's no [XamlCompilation(XamlCompilationOptions.Compile)] in your MyPage.Eren Shen
Nope there is no attribute on the MyPage classOmar Himada

1 Answers

2
votes

To include native controls in your Xamarin.Forms page you will need to create a custom control and platform renderer. See the official documentation for full walkthrough.

In a gist, you first you declare a new control in your shared project:

public class MyCustomViewControl : View
{

}

Now in the Android project you create a custom renderer, that will use your custom Android view to display natively:

public class MyCustomViewRenderer : ViewRenderer<MyCustomViewControl, MyCustomViewGroup>
{
    MyCustomViewGroup viewGroup;

    public MyCustomViewRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<MyCustomViewControl> e)
    {
        base.OnElementChanged(e);

        if (Control == null)
        {
            viewGroup= new MyCustomViewGroup(Context);
            SetNativeControl(viewGroup);
        }
    }
}

You will also use the renderer to setup events, etc. on the native side.

The renderer is recognized and registered by Xamarin.Forms thanks to the attribute, that can be in the same file as the Renderer, above the namespace:

[assembly: ExportRenderer (typeof(MyCustomViewControl), typeof(MyCustomViewRenderer))]