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.
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
Although we'll add more later, we'll add just one property to store an
XamarinShowCardView is now available for use in our Xamarin.Forms pages. We can change our
ItemTemplate to use a
The only child view we'll need in the
ViewCell is our
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 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.
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
. This approach lets us apply a custom, native look and feel to our otherwise cross-platform Xamarin.Forms app.
Ed Buhain applies cutting-edge technology to professional software development and technical project management as well as his personal hobbies, such as building social media applications, home improvement, and cooking. Ed has over 18 years of professional experience in software development and technical project management. He maintains several professional certifications, including CSD, CSM, CSPO, CSP, MCPD, PMP, and Xamarin certifications.