- Xamarin
- Xamarin.Android
When you develop a Xamarin.Android application, you often need to pass parameters between activities.
Android provides you different way to achieve that, one of these is to use Parcelables
.
Parcelables
give you the ability to pass an entire model between two activities in Android applications.
To start this tutorial, you will find a starter project on Github.
This project is a simple Xamarin.Android project with one .NET Standard library for the shared code. The goal of this tutorial is to pass a model between two activities.
In our scenario we have a first activity : MainActivity
to be original ;) that show us the first and last name of a user.
We have all the data about the user in this activity and we want to pass it to the second activity : DetailActivity
.
The model that we will pass between the activities is a User :
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string Country { get; set; }
}
If you launch the app now, you will get a simple page, with the first and last name displayed and a button. Nothing fancy for now.
In our Xamarin.Android project we need to create a parcelable class, that will allow you to pass the User
from one activity to
the other.
Let’s create a new folder called : Parcelables
and in this one, create a new file : UserParcelable
First we need to implement Java.Lang.Object
and IParcelable
:
public class UserParcelable : Java.Lang.Object, IParcelable
{
public UserParcelable()
{
}
public int DescribeContents()
{
throw new NotImplementedException();
}
public void WriteToParcel(Parcel dest, [GeneratedEnum] ParcelableWriteFlags flags)
{
throw new NotImplementedException();
}
}
The default constructor is mandatory for the Parcelable Creator
class that we will see later in this tutorial.
Passing an object using Parcelable
consist in serializing and deserializing it. It’s the same concept as using JSON when you call an API.
Let’s first add a User
object to our class.
public User User { get; set; }
To pass data with in the Parcelable
we need to use a Parcel
, it contains all the data and object references that we want to send.
The WriteToParcel
method is the serialization part :
public void WriteToParcel(Parcel dest, [GeneratedEnum] ParcelableWriteFlags flags)
{
dest.WriteLong(User.Id);
dest.WriteString(User.FirstName);
dest.WriteString(User.LastName);
dest.WriteInt(User.Age);
dest.WriteString(User.Address);
dest.WriteString(User.City);
dest.WriteString(User.Country);
}
As we can see above, we need to write each parameters to the Parcel
object depending on their type (Long, Int, String…)
The DescribeContents
method describe the kinds of complex objects contained in this Parcelable
.
In our example, because we only have simple types in our User
model, we just need to write return 0
.
public int DescribeContents()
{
return 0;
}
We now need to create the Parcelable
constructor and re-assign all the parameters of our User
model in the same order that we defined in the WriteToParcel
method :
private UserParcelable(Parcel parcel)
{
User = new User
{
Id = parcel.ReadLong(),
FirstName = parcel.ReadString(),
LastName = parcel.ReadString(),
Age = parcel.ReadInt(),
Address = parcel.ReadString(),
City = parcel.ReadString(),
Country = parcel.ReadString()
};
}
Now we need to create another class that will create instances of our UserParcelable
class.
Here a generic class that you can add in your Parcelables
folder, so you will be able to use it for every new Parcelable
you will create.
public class GenericParcelableCreator<T> : Java.Lang.Object, IParcelableCreator where T : Java.Lang.Object, new()
{
/// <summary>
/// Function for the creation of a parcel.
/// </summary>
private readonly Func<Parcel, T> _createFunc;
/// <summary>
/// Initialize an instance of the GenericParcelableCreator.
/// </summary>
public GenericParcelableCreator(Func<Parcel, T> createFromParcelFunc)
{
_createFunc = createFromParcelFunc;
}
/// <summary>
/// Create a parcelable from a parcel.
/// </summary>
public Java.Lang.Object CreateFromParcel(Parcel parcel)
{
return _createFunc(parcel);
}
/// <summary>
/// Create an array from the parcelable class.
/// </summary>
public Java.Lang.Object[] NewArray(int size)
{
return new T[size];
}
}
So we can use this class in our UserParcelable
class :
private static readonly GenericParcelableCreator<UserParcelable> _creator
= new GenericParcelableCreator<UserParcelable>((parcel) => new UserParcelable(parcel));
[ExportField("CREATOR")]
public static GenericParcelableCreator<UserParcelable> GetCreator()
{
return _creator;
}
This will create an instance of the Parcelable
object for us.
Now that we are ready to pass data between our two pages, let’s get back to the MainActivity
and in the SeeMoreBtn_Click
method that
I have already prepared for you, we have to create a Parcelable
and send it to the DetailActivity
:
Intent intent = new Intent(this, typeof(DetailActivity));
UserParcelable parcelable = new UserParcelable();
parcelable.User = _user;
intent.PutExtra(DetailActivity.UserParcelableExtra, parcelable);
StartActivity(intent);
In the DetailActivity
we receive our User
object, to do that, add these lines in the OnCreate
method :
UserParcelable parcelable = (UserParcelable)Intent.GetParcelableExtra(UserParcelableExtra);
UpdateView(parcelable.User);
If you build the project you will get this error :
Error XA4210: You need to add a reference to Mono.Android.Export.dll when you use ExportAttribute or ExportFieldAttribute. (XA4210)
As the error mentions, we need to edit the references of our Xamarin.Android project and add the Mono.Android.Export.dll
to get it works.
Now rebuild the project and you will see the user data in the DetailActivity
.
Congrats ! Now you know how to use Parcelables
in your Xamarin.Android projects !
You will find all the source code in the final
branch of the Github repository.
Happy codding !
You liked this tutorial ? Leave a star in the associated Github repository!