Build Android Apps With Xamarin Using Portable Class Libraries
This post will show how to use Xamarin.Android and Visual Studio 2013 to build an app for Android reusing an existing portable class library.
Background
In a previous post, Using Portable Class Libraries to Reuse Models and ViewModels, I showed an example of creating a portable class library (PCL) and how to use it with several types of clients (WPF, Windows 8, and Windows Phone). This post is going to show how to reuse the same PCL library to create an app for Android with Visual Studio 2013 and Xamarin.Android.
When we created the PCL library named “ReusableLibrary” in the previous post, we configured its targets to be .NET Framework 4.5, Windows 8, Windows Phone Silverlight 8, Xamarin.Android, and Xamarin.iOS. Note that you only get Xamarin.Android and Xamarin.iOS if you have the Xamarin tools installed.
Since our PCL library targets Xamarin.Android, we can show how to reference the library and reuse it within the context of an Android app.
Create the Xamarin Project
Once you have Xamarin.Android installed and the emulators configured, you can use Visual Studio 2013 to create a new Android Application.
I added this project to the existing solution that already contains my PCL library named “ReusableCode” as well as the implementations for Windows Phone, Windows 8, and WPF. Once the project is created, the Android project contains a few files that we will modify (Main.axml, strings.xml, and Activity1.cs).
Create the UI
When you create a new project, your form will contain a button that says “Hello World, Click Me”. Open strings.xml and change the resource name from “hello” to “buttonText”, and change the resource value to “Update Customer”.
Now go to the Main.axml file and modify the layout. Our UI will be a simple list, 3 text boxes, and a button.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/listView1" />
<EditText
android:inputType="number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/customerID" />
<EditText
android:inputType="textPersonName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fullName" />
<EditText
android:inputType="phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/phone" />
<Button
android:id="@+id/MyButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/buttonText" />
</LinearLayout>
Notice that our button uses the resource string ID “buttonText” that we modified in the previous step.
Implement the Code
The last part we want to do is to create the app itself, referencing our PCL library named “ReusableLibrary” (detailed in the post Using Portable Class Libraries to Reuse Models and ViewModels). We add a reference to the ReusableLibrary project.
We now edit the Activity1.cs file. Our app screen contains a list view, we want to receive an event when the list view is clicked. The easiest way to do this is to add the ListView.IOnItemClickListener interface to our Activity class.
Add a field to contain the CustomerViewModel.
This is not like the nice XAML model that has data binding baked into it, we are going to have to write a little code to reuse the Model and View Model from our PCL library. Our ViewModel has a property to obtain a list of customers. We need to get a string array of customer names, because we are going to use the ArrayAdapter<string> to display the items (you’ll see this in a subsequent step). In the OnCreate method, we add the following code.
//Copy the items into a string array so we can
//use ArrayAdapter<string>
string[] customers = new string[viewModel.Customers.Count];
int index = 0;
foreach (Customer c in viewModel.Customers)
{
customers[index] = c.FullName;
index++;
}
If we want to reference controls in the UI, we do that by using the FindViewById method, providing the ID of the control from the Main.axml file that we edited previously. Using this method, we can now set the Adapter property of the ListView control to set its data source. We also tell Android to use the SimpleListItemView1 view that comes out of the box, relieving us of having to write our own view. We also wire up the event handlers for when an item is clicked and when the button is clicked.
//Set the data source for the listView
ListView listView = FindViewById<ListView>(Resource.Id.listView1);
listView.Adapter = new ArrayAdapter<string>(
this,
Android.Resource.Layout.SimpleListItem1,
customers);
//When an item is selected, call our method
listView.OnItemClickListener = this;
//Wire up the button click
Button button = FindViewById<Button>(Resource.Id.MyButton);
button.Click += OnButtonClick;
Let’s implement the listView.OnItemClickListener functionality, which allows us to select an item from the list. Just as before, we use the FindViewById method to find a control by its ID in the Main.axml file. We then find the current item by its position. Then I do something a little screwy… I look through all of the Customer objects and find the one whose name matches. This is a hack due to the fact that I am using the ArrayAdapter<string>. I could have written a custom adapter and just referenced the item by its ID, but I wanted to get something working quickly. I leave it as an exercise to the reader to replace this hack with your own adapter. Once we set the current customer, we can then populate the other controls.
public void OnItemClick(AdapterView parent, View view, int position, long id)
{
ListView listView = FindViewById<ListView>(Resource.Id.listView1);
object o = listView.Adapter.GetItem(position);
Customer c = viewModel.Customers.Find(x => x.FullName.Equals(o.ToString()));
viewModel.CurrentCustomer = c;
EditText customerID = FindViewById<EditText>(Resource.Id.customerID);
customerID.Text = c.CustomerID.ToString();
EditText fullName = FindViewById<EditText>(Resource.Id.fullName);
fullName.Text = c.FullName;
EditText phone = FindViewById<EditText>(Resource.Id.phone);
phone.Text = c.Phone;
}
Let’s implement the button.Click event handler, which we use to update the data. Just as we did previously, we find the control using the FindViewById method using its name from the Main.axml file. We then modify the current customer’s phone and execute our RelayCommand from our PCL library.
public void OnButtonClick(object sender, EventArgs e)
{
EditText phone = FindViewById<EditText>(Resource.Id.phone);
viewModel.CurrentCustomer.Phone = phone.Text;
viewModel.UpdateCustomerCommand.Execute(null);
}
The End Result
The nice thing about using Xamarin.Android with Visual Studio 2013 is that you get all the debugging capabilities that you are used to. Simply press F5 to start debugging, and the project is deployed to the emulator. When the screen first appears, our text boxes do not have any data. We see the list of customers, and we can select one.
When we select one of the items from the list, the textboxes are populated with data.
We can change the phone number and click the button. That will execute our RelayCommand in our view model, updating the customer object.
Summary
This was not a summary of best practices for building an Android app using Xamarin.Android, and it certainly is not a lesson in how to build a nice-looking UI This post demonstrates how you could reuse models and view models in a PCL library from an Android application built using Xamarin tools.
For More Information
Using Portable Class Libraries to Reuse Models and ViewModels