How We Built a Multisection Solution for Android using Kotlin

Artem Kholodnyi

Android developer

SHARE

124

“Multiselection can be quite tricky on mobile,” says our designer, Vitaly Rubtsov. Multiselection solutions found in most applications – Telegram, Apple Music, Spotify and others – are usually not that flexible and can be quite uncomfortable to use.

When creating your own playlists in Apple Music, for example, it can be confusing to understand which songs have already been added without switching between several screens or endlessly scrolling through a list of selected songs.

And the situation may get even worse if we decide to apply filters. In this case, the list of compositions may change once we’ve applied a filter, but the compositions you’ve already selected may not be displayed at all. Vitaly decided to solve this problem with his own concept for multiselection (originally published to Dribbble).

The idea is just brilliant: the screen is divided into two parts, so you can always “see and manage what you’ve selected without having to leave the current view,” as Vitaly explains. Filters are only applied to the main list from which you select, but are not applied to your list of selected items.

That's when I knew that Vitaly’s multiselection concept must be brought to life by any means; so I started my work on the component almost immediately. And now let’s see how the Android Multiselection Animation was born.

Implementing the component

The animation’s logic seems straightforward, yet it has a few catches.

The component has a ViewPager with two RecyclerViews. We can make a ViewPager page narrower than the screen by overriding the getPageWidth method in the ViewPager adapter and returning a floating number between 0 and 1.

A ViewPager has two pages, each with the RecyclerView. Unselected items are on the left list. Selected items are on the right one. For instance, if you click an unselected item, a few things will happen:

The clicked item is deleted from the unselected items list and added to the container that holds both lists.

Item position in the selected items list is determined. (The unselected list always has its items sorted alphabetically. The selected list has its items in the order they were selected)

A hidden item is added to the selected items list.

The translation animation is run for the clicked item.

The clicked item is deleted and the hidden item in the selected list is shown.

The most tricky part of this sequence is removing a view from the layout manager; otherwise, the layout manager will try to recycle it, which will cause an error since we are deleting the view from RecyclerView:

sourceRecycler.layoutManager.removeViewAt(position)

Technology stack

I chose the Kotlin programming language as the tool for this job. The main benefits of Kotlin are its concise syntax and virtually no NullPointerException crashes compared to Java. (And, as a result, Kotlin makes for happier developers.) Here are a few useful Kotlin features that made my life easier while I was implementing this library:

Extension functions

With extension functions, you can ‘extend’ pre-defined classes with useful methods – even classes you don’t own!

Take the Android View class, for example. Often you need to remove a view from its old parent and attach it to a new one:

After defining the above method, you can now call it from anywhere in your project like this:

Or, you can even write a method that removes the view from its current parent and attaches the view to a new one:

view.attachTo(newParent)

One more advantage is that you can add the (strangely absent)setScaleXY method. I’ve hardly ever seen setScaleX used without setScaleY, or vice versa. So why not have a single method that sets both scales? Let’s do it:

fun View.setScaleXY(scale: Float) {
scaleX = scale
scaleY = scale
}

You can find more examples of how we used extension functions in the Extensions.kt file in the library’s source code.

Null safety

Kotlin’s null safety feature is a game changer. The ‘?.’ operator works just like ‘.’ but if the object it’s called upon is null, ‘?.’ won’t throw a NullPointerException, but will return null instead:

The code above, for instance, won’t crash even if findViewHolderForAdapterPosition returns null.

Collections

Kotlin comes with stdlib, which includes a lot of neat collection functions like map and filter. These methods are widespread, and basically exhibit the same behavior across programming languages, including Java 8 (streams). Unfortunately, streams are still not available out of the box for Android development.

For our multiselection library, we needed to animate transparency of every view child except the child with a specific id. The following Kotlin code does the job well:

Accomplishing the same in Java would take perhaps twice as many lines of code as we used here.

Better syntax

In general, Kotlin’s syntax is more concise and readable than Java’s.

One example is the when expression. Unlike switch (Java’s analogue), Kotlin’s when expression returns a value, so you have to assign it to a variable or return it from a function. That feature in and of itself allows for shorter and more readable code:

Remember those Facebook reactions? Well, we aren't Facebook but we love reactions too. They can give us valuable insights on how to improve what we're doing. Would you tell us how you feel about this article?