Flexibility for your app

Hey everyone!

Have you ever worked on a very nicely knit portion of an app? That is, an element that is being used over and over so that you don’t have to reinvent the wheel every time?

Try this with a singleton class or type. This design pattern is really useful for symmetrical data that can be passed in multiple times from a JSON element. Therefore, singleton-models from here are very nice, no problem!

Now, try this with UI elements. Let’s take a ViewHolder from the Android SDK for example.

We have a base item element that our CustomViewHolder gets where it takes some fields like name, address, and profile picture. From there, it’s also possible to add in some nice helper methods to do some extra work like getting data from the server. However for simplicity, we’ll just focus on our CustomViewHolder. Therefore, we’ll have something like this:

public class CustomViewHolder : RecyclerView.ViewHolder
{
    public ImageView IvProfilePicture;
    public TextView TvName, TvAddress;

    public CustomViewHolder(View itemView)
    {
        IvProfilePicture = itemView.FindViewById<ImageView>(Resource.Id.ivProfilePicture);
        TvName = itemView.FindViewById<TextView>(Resource.Id.tvName);
        TvAddress = itemView.FindViewById<TextView>(Resource.Id.tvAddress);
    }
}

// ... we'll assume that the XML layout already has these fields

Cool! 🙂

Now, we’ll consolidate our CustomViewHolder into our CustomRecyclerViewAdapter, and then just populate along with the data we will need along with the constructor. Again, cool, it works as we will want it to! 🙂

Now let’s say that our design changed in one of the pages that uses this CustomRecyclerViewAdapter. There are still remaining view elements, with just one additional view element to the list item.

Therefore, depending on the screen, we’ll just toggle this view element’s visibility to Visibility.Gone or Visibility.Visible, right?

If it is a simple dumb view element, then that will work. However, if there is a control element involved, then it’s more complicated than that. 🙁

We can’t just use viewElement.Click += (objectSender, eventArg) => { // code for what should be done after user clicks }; Why? A RecyclerView will reuse elements as we move along, and therefore, we are incrementing click events instead of replacing them every single time.

Also, our constructor can’t support a ClickEventArgs type as a parameter since we will have different views all the time. Therefore, what is the solution?

Being quite familiar just with Android development, we can go back to our old View’s setOnClickListener(View.OnClickListener listener) method!

Well, almost 😉

In Xamarin.Android, we can’t just override the methods that the anonymous classes or anonymous interfaces give us in plain Android development.

Rather, we will need to make our own extension classes in C# that will support the same functionalities that is already provided in plain Android. So, let’s do that!

public CustomOnClick : Java.Lang.Object, View.IOnClickListener
{
    readonly Action action;

    public CustomOnClick(Action action)
    {
        this.action = action;
    }

    protected override void OnClick()
    {
        action.Invoke();
    }
}

Now in our CustomOnClick class, we have just made an Action that work like anonymous methods in Java. Therefore, we can now do this:

viewElement.SetOnClickListener(new CustomOnClick(() => { // code for what should be done after user clicks }));

Now every time we scroll our RecyclerView, we are sure that our clicks get reset each time with the specific functionality we want exclusive to the item! Now, we have a flexible RecyclerView.Adapter! 🙂

In this case, we have inherited from Java’s Object class to avoid IntPtr handles and Dispose since Android should handle all of this on its own regardless. In the Android SDK, this is mainly with interfaces described here, but there should be no need to do this for classes.

By the way, this works well with other portions where by default Xamarin.Android doesn’t provide their own interfaces for any other Android anonymous classes. 😉

Until next time!

Brian.