Going Native: Using Android Views In Xamarin.Forms
We previously walked through how to get started with a cross-platform Xamarin.Forms project, but what if we started with an Android app built in Android Studio? Here's a way to re-use a lot of our Android code and layouts with Xamarin.
In the previous post, we customized a Xamarin.Forms ListView
with an ImageCell
to display a list of TV shows.
The ImageCell
is a convenient tool to get us started. However, we may have to tailor our app's appearance to meet platform-specific design requirements. We might save time if we have existing code and views we could port to Xamarin.Forms.
A Xamarin.Forms Custom View
We can create our own Xamarin.Forms view by extending the View
class.
Although we'll add more later, we'll add just one property to store an ImageUrl
.
Our XamarinShowCardView
is now available for use in our Xamarin.Forms pages. We can change our ListView
's ItemTemplate
to use a ViewCell
.
The only child view we'll need in the ViewCell
is our XamarinShowCardView
.
A Xamarin.Android View
In our Android project, we can add an Android layout. Here we're using an Android ImageView
to display an image for each show.
Even though we're using Visual Studio, we're using the same Android XML format we might use in Android Studio. However, in our Xamarin project, we're using the .axml
extension to distinguish our Android XML from Xamarin XML.
Now that we have our Android layout, we can create a ShowCardView
, our own version of an Android CardView
.
An Android CardView
is just a FrameLayout
with some extra formatting, such as rounded corners. We're adding more customizations to the layout by calling Inflate
with our own layout. We've also provided an ImageUrl
property so that our Xamarin components can set the image source for each TV show.
Connecting Xamarin.Forms & Xamarin.Android
Now that we've built our traditional Android controls, we need to tell Xamarin.Forms to use them. We do that using a custom renderer.
We use our ExportRenderer
attribute to tell Xamarin.Forms to use a ShowCardRenderer
(our extension of the Xamarin ViewRenderer
) to render a XamarinShowCardView
. If you've customized a UI for a TV app, you'll find that the ViewRenderer
is quite similar to the Presenter
in the Leanback support library: they're both responsible for displaying our native UI.
A ViewRenderer
provides the onElementChanged
method, where we can instantiate our native ShowCardView
and call SetNativeControl
to set the Control
property. This is also where we set the ImageUrl
property in our ShowCardView
, which in turn calls our LoadImage
method to load the image.
A Bindings Library (How'd You Load That Image?)
Although there are many ways to download an image from the web, we can save time by re-using the Picasso image downloading and caching library for Android. To do this, we create a Bindings Library project, an assembly containing Managed Callable Wrappers for Java types.
Our Bindings Library template includes a Jars
folder, to which we've added the Picasso jar file (available for download from the Central Repository).
We can now reference our Bindings project, which makes the native package available to our view. We can reference our Java packages in our C# code!
Native Pixel Perfection
We can keep building our custom ShowCardView
and work on our layouts and styles just like we might have done in Android Studio.
And in the end, our Xamarin.Forms ListView
uses our own Android native layout and controls!
Even though we might use Xamarin.Forms for our shared, cross-platform views, we aren't limited to only those. We often want to take advantage of individual platform features such as Android Leanback and the Android CardView
. This approach lets us apply a custom, native look and feel to our otherwise cross-platform Xamarin.Forms app.