How to add Xamarin Forms content as a subview in Xamarin.Android and Xamarin.iOS

We have a "legacy" Xamarin.Android and Xamarin.iOS project. We would like to inject a Xamarin Forms component as a subview into a "native" Android and iOS view. The component is only available as a Xamarin Forms component and it is too expensive rewrite the entire app to Xamarin.Forms.

The main question is how can we add complex Xamarin.Forms layouts as a subview in a "native" Xamarin.Android or Xamarin.iOS view?

We have done some proof of concept work, and have sucessfully injected a XF third party component as a single Xamarin Forms element. However, this technique does not fully work when we inject a layout with children elements as eg a StackLayout.

Attached is a pure test project with both iOS and Android code.

The central pieces of code is e.g in MainActivity.cs and ViewController.cs

MainActivity.cs:
<br /> protected override void OnCreate (Bundle savedInstanceState)<br /> {<br /> base.OnCreate (savedInstanceState);<br /> Xamarin.Forms.Forms.Init (this, savedInstanceState);<br /> SetContentView (Resource.Layout.Main);</p> <pre><code> _stackedLabels = new StackedLabels (); var renderer = Xamarin.Forms.Platform.Android.Platform.CreateRenderer (_stackedLabels.LabelStack); // LabelStack is a StackLayout var rootLayout = this.FindViewById<LinearLayout> (Resource.Id.root); rootLayout.AddView (renderer.ViewGroup); }

ViewController.cs:
<br /> public override void ViewDidLoad ()<br /> {<br /> base.ViewDidLoad ();</p> <pre><code> _stackedLabels = new StackedLabels (); var renderer = Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (_stackedLabels.LabelStack); // LabelStack is a StackLayout var rootLayout = this.View; rootLayout.Add (renderer.NativeView); renderer.NativeView.Frame = this.View.Bounds; renderer.SetElementSize (new Xamarin.Forms.Size (this.View.Bounds.Width, this.View.Bounds.Height)); // Companion method not found for Android since we do not know exact size in the Android activity OnCreate method. }

Here, we create a renderer and adds the "native view/view group" manually to the iOS root view present in the view controller or the Android layout which is loaded by the activity.

Expected result would be that the entire StackLayout is displayed with its children. However, none of the children are visible.

We think this has do with how Xamarin.Forms calculates sizes for the VisualElements in the StackLayout, but we have not succeded to trigger
this calculation.

We also note that the iOS renderer sucessfully computes sizes when WidthRequest and HeigthRequest is added to the childs of StackLayout, but not when only HorizontalOptions and VerticalOptions are set.

The main question is how can we add complex layouts as a subview in a "native" Xamarin.Android or Xamarin.iOS view?

Best Answer

Answers

Sign In or Register to comment.