Intro
Within Xamarn.Forms, we may find ourselves having to show a custom page per device platform (i.e. IOS, Android, etc.) In my case, I needed to display a content page that had a map along with some other controls. In this post I will demonstrate how to load a native android page within a Xamarin.Forms app.
Steps
- Add a new class to your Xamarin.Forms project and call it “CustomPage”.
Solution Explorer:
Class:
using Xamarin.Forms; namespace Pickup { public class CustomPage : ContentPage { } }
2. In your Xamarin.Forms project, add a XAML file.
Implement the following XAML:
<?xml version="1.0" encoding="utf-8" ?> <local:CustomPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps" xmlns:local="clr-namespace:Pickup;assembly=Pickup" x:Class="Pickup.MapPage" />
3. Add a Layout folder to your Android project as well as an axml file.
4. Implement the axml file as the following:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <View android:layout_height="0dp" android:layout_width="fill_parent" android:layout_weight="1" /> <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map" android:layout_width="200dp" android:layout_height="200dp" class="com.google.android.gms.maps.MapFragment" /> <TextView android:id="@+id/textView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="top"/> <View android:layout_height="0dp" android:layout_width="fill_parent" android:layout_weight="1" /> <Button android:id="@+id/button_code" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Locate Me!" /> </LinearLayout>
5. Add a custom renderer to your Android project by adding a new class.
6. Implement the renderer with the following code:
[assembly: ExportRenderer(typeof(CustomPage), typeof(MapPageRenderer))] namespace Pickup.Droid { public class MapPageRenderer : PageRenderer { Android.Views.View _view; protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Page> e) { base.OnElementChanged(e); var activity = this.Context as Activity; _view = activity.LayoutInflater.Inflate(Resource.Layout.MapLayout, this, false); AddView(_view); } protected override void OnLayout(bool changed, int l, int t, int r, int b) { base.OnLayout(changed, l, t, r, b); var msw = MeasureSpec.MakeMeasureSpec(r - l, MeasureSpecMode.Exactly); var msh = MeasureSpec.MakeMeasureSpec(b - t, MeasureSpecMode.Exactly); _view.Measure(msw, msh); _view.Layout(0, 0, r - l, b - t); } } }
7. When you run your app, you should see something like this:
Conclusion
In conclusion, we may find ourselves having to show a custom page with Xamarin.Forms per device platform (i.e. IOS, Android, etc.) In my case, I needed to display a content page that had a map along with some other controls. In this post I demonstrated how to load a native android page within a Xamarin.Forms app.
NOTE:
Scott Nimrod is fascinated with Software Craftsmanship.
He loves responding to feedback and encourages people to share his articles.
He can be reached at scott.nimrod @ bizmonger.net