Displaying images in an Android application: delegates, tests and no pain

Displaying images in an Android application: delegates, tests and no pain

Revolut app

Our application has many types of pictures to display – there are lists of transactions with different icons, lists of cards, Lottie animations, gifs. I’ll show you how we work with pictures using the example of a list of transactions.

Our list of transactions has several dozen types of cells. For example, we’ll take five:

Different types of transactions where we show the picture

In each case, the picture is taken from a separate source or generated.
How the standard way of displaying pictures works

Let’s create an adapter for such a list.

class TransactionsAdapter: RecyclerView.Adapter () {
private var items = mutableListOf ()

override fun onCreateViewHolder (parent: ViewGroup, viewType: Int): ViewHolder {
    val view = LayoutInflater.from (parent.context)
        .inflate (R.layout.view_transaction, parent, false)
    return ViewHolder (view)
}

override fun onBindViewHolder (holder: ViewHandler, position: Int) = Unit

override fun getItemCount () = items.size

class ViewHolder (itemView: View): RecyclerView.ViewHolder (itemView) {
    private val imageView: ImageView = itemView.findViewById (R.id.image)
}

}

This is what the standard adapter template for RecyclerView would look like. Let’s implement value binding:

override fun onBindViewHolder (holder: ViewHandler, position: Int) {
val transaction = items [position]
when {
transaction.isContactWithAvatar () -> {
// Load and display the avatar
}
! transaction.isContactWithAvatar () -> {
// Display avatar
}
transaction.isMerchantWithAvatar () -> {
// Load and display the avatar
}
! transaction.isMerchantWithAvatar () -> {
// Load image from source
}
}
}

A footcloth of conditions appears, because inside the adapter we build separate logic for each type of transaction. You can complicate and use your ViewType for each source. Moreover, the adapter contract pushes for this:

override fun getItemViewType (position: Int): Int {
val transaction = items [position]
return when {
transaction.isContactWithAvatar () -> VIEW_TYPE_CONTACT_WITH_AVATAR
! transaction.isContactWithAvatar () -> VIEW_TYPE_CONTACT_WITHOUT_AVATAR
transaction.isMerchantWithAvatar () -> VIEW_TYPE_MERCHANT_WITH_AVATAR
! transaction.isMerchantWithAvatar () -> VIEW_TYPE_MERCHANT_WITHOUT_AVATAR
else -> VIEW_TYPE_UNKNOWN
}
}

Considering that in our case there can be several dozen types of transactions, the standard way of implementing the adapter is not suitable.
How to improve the adapter

We can distinguish two main approaches to extension – ViewType or delegates. The rest are not specifically mentioned: in essence, they will be similar to the second approach.

The first option – ViewType – can be used when the application is simple, that is, it contains one simple list and, for example, a couple of screens. This method is not suitable for us, because such adapters cannot be reused. If we expand the adapter by adding new ViewType, the adapter will grow uncontrollably. In addition, we will have to create our own adapters for each screen.

You may also like

Additional Considerations for Android App Development

Additional Considerations for Android App Development

Adapting to Emerging Technologies The Android platform is constantly evolving with new technologies such as artificial intelligence (AI), machine learning...

Key Considerations in Android App Development

Key Considerations in Android App Development

Developing applications for Android has become increasingly significant as the platform continues to dominate the global smartphone market. To create...

The Role of AI in Personalizing User Experience Across Digital Platforms

The Role of AI in Personalizing User Experience Across Digital Platforms

In the ever-evolving landscape of the digital age, the intersection of technology and personal preference has given rise to a...

Cybersecurity in Modern Vehicles: Ensuring Safety in the Digital Age

Cybersecurity in Modern Vehicles: Ensuring Safety in the Digital Age

The integration of digital technology into automotive design has transformed the humble automobile into a nexus of connectivity and innovation....

Back to Top