Android Dev’s: About quick work with lists

Hello! My posts is desire to help with some elements of Android. If you’re developer, which not yet formed self-algoritm to work with lists — that material may be useful. In generally, I would like to offer ready-made solutions for Android development, revealing in the narrative some thoughts about how I came to this.

In Article:

  • form a several base classes and interfaces for work with RecyclerView, RecyclerView.Adapter
  • added library from Android Jetpack (optional, first without it)
  • for a quick development — variant of template at the end of article

Introduction

Well! We all forgot about a ListView and safely write code with a RecyclerView (Rv). Those times when we realized the ViewHolder pattern, we have sunk into oblivion. Rv provides us a set of ready classes for list implementation and a large selection of LayoutManagers for displaying them. In fact, looking at a lot of screens, the list can represent the majority of them. More detailed history of development we were recieved on Google I / O.

But there are always some problems! Standard searches on Stackoverflow suggest common solutions that lead to a copy-paste, especially in the Adapter’s implementation area. At the moment, Rv existing already three years old. So much information about it and so much libraries with implementations. But what can you do, if you don’t want all functions or if you read the code and don’t agree with authors?

For these three years, Android finally officially accepted Kotlin, improved code readability, published many interesting articles about Rv that fully reveal its capabilities.

Article goal — build of foundation or carcass for fast lists development. You can to add logic from application to application excluding extra code. This approach is better that another’s library — in your classes you have an opportunity to deal with code processing and control cases, not getting stuck in someone’s decisions.

Let’s think logically and from the beginning

Our decisions about functionallity of components will be closing on interface. Some class will be implementing this interface, but if we will seeing copy-pasta, we will exclude this in abstract class, and than — extends from it. I will show my implementations, but my goal is that you’ll be thinking in this direction, that’s all! Once again — the plan is:

  • Set of interfaces
  • Abstract class excluding copy-pasta (if it’s necessary)
  • Specific class with unique code
* You can to use your own realisation of Interfaces!

What Adapter can to do with list? You can get the answer if look some example. If we look code of RecyclerView.Adapter, we will getting several hints. I think that the methods look something like this:

*When I watched my projects, I had been finding several another methods like getItemByPos(position: Int), even subList(startIndex: Int, endIndex: Int). One’s more: Use the functions, which you really need in current project, extend interface if its not enough. But I advise you to take minimum on the start — because you’ll might to avoid extra lines of code. Don’t forget — real implementation take more lines and degrades the readability of the project.

Pay attention to the generic <T>. In common case, adapter works with any type of item, and we’ll be using two types. First type simplified and will look like:

This really makes sense — we talking about list element, then each element must have a layout, and we can to reference on it by layout id.

More advanced approaches involve delegates and wrappers , but I think that it’s excess because didn’t see it in official documentation. If you need more functionality — use approaches by link above.

Now let’s merge IBaseListAdapter with interfaces and next class will be abstract:

*Pay attention on function getItemViewType(position: Int). We need some integer key, witch connect layout and ViewHolder for Rv. We can to use item layoutId for this purpose, because every time Android generate it with unique value, so we use this and inflate itemView for our viewholders in inflateByViewType() method (8 stroke)

List creating

Let’s get settings screen for example. Of course, we can use standard variant, but what if we’ll get a task do something more refined? I prefer build this screen like list with items. Let us consider the following case:

We can to see two different elements in list, so SimpleAdapter and RecyclerView are perfect for this case!

Let’s get it started! Our layouts for items:

Then, define classes, inside of which we want to pass values that interact with the list: first class will contain a title and a some value from response (we will use caps, will talk about requests next time), second class will contain a title and boolean for checked action. We need to differ our switch classes, let’s define id inside it:

In SimpleAdapter realization we need to define ViewHolder for every item:

Finally, implementation class of our SimpleListAdapter:

We did it! Now let’s write code in Activity and we can launch programm

As a result, when building a list, all the work boils down to the following:

  1. Determine the quantity of elements. Think about layouts, you always need watch on the screens
  2. Select title for items. I use this rule: SomethingItem.kt, item_something.xml, SomethingViewHolder.kt
  3. Define adapter for items. If you’re not pretend on optimization, you may to use common adapter. But, in big projects I advice to use several adapters, because in first variant the method onBindViewHolder() inevitably grows and suffers code readability. Also, a programm everytime for every item use it and onCreateViewHolder() method.
  4. Run the code and rejoice! =)

JetPack

Until this moment we used the standard approach binding data from Item.kt to item_layout.xml. But we can unify method onBindViewHolder(), keep minimal logic in this and write it in item and layout.

Let’s open the official site of Android JetPack:

Note on the Architecture chapter, first tab. Android Databinding — a very extensive topic, I would like to talk about it in more detail in other articles, but now we will use only within the current— we will use ours Item.kt as a variable for item.xml (you can call it “view model” for layout also).

At the time of this writing, DataBinding could be implement in the project like this:

So, start again from the base classes. Interface for an item extends previous

Also, we will extend our ViewHolder, because using Data Binding Library. We will pass ViewDataBinding, then safely forget about some extra code with viewholders, for example, about findViewById() method

Same approach is using here but it so shorter on Kotlin, isn’t it? =)

Adapter:

Note that the methods onCreateViewHolder(), onBindViewHolder() will not any grows.Totally, you get the one adapter for any screens, any list elements.

Our items:

And now we see, there the logic of method onBindViewHolder() is gone. There is Android DataBinding action here, our layout is supported by the own view model, and it handles onclicks, animation, reqests e.t.c. What you want — all possible! You can do this with Binding Adapters, that allow to connect view with any types of the data. Furthermore, you can upgrade Binding Adapters via Two-Way Binding. I’ll use it in some next articles, now we need just one Binding Adapter:

After this, we connect values of items with layouts:

app:switchListener=”@{vmSwitch.listener}” — here we use BindingAdapter

Quite for justified reasons, some might think that we write a lot more code in the xml — but this is a matter of the knowledge of the Android Databinding Library. It complements layout, quickly readable and take a boilerplate code. I think Google is going to support this library well, since it is the first in the Architecture tab, in the Android Jetpack. Try to change in any project MVP on MVVM — and you’ll be surprise.

So! Code in SettingsActivity not changed except we change Adapter:

Conclusion

We created the algorithm for the list building and tools for work with it. In my case I always use DataBinding, all preparation is reduced to initialization of base classes by folders, define layouts and binding for values in .kt files.

Accelerate Development

For quick working I had been use templates by Apache for Android Studio and wrote own templates with a short demonstration how it works. I really hope that it will be useful to someone. Note that call template need from root folder of project. this is because applicationId parameter of globals in template can be wrong if you change it in build.gradle , but not a packageName so I used this. You can find more information about templates by links below

References/media

1. Modern Android development: Android Jetpack, Kotlin, and more (Google I/O 2018, 40 m.) — short guide what technologies in Android are relevant, and story about the Rv evolution;

2. Droidcon NYC 2016 — Radical RecyclerView, 36 m. — detailed report about Rv by Lisa Wray;

3. Create a List with RecyclerView — official documentation

4. FreeMarker manual — useful approach, which help to create classes by the one click and remove a responsibility to write boilerplate code

5. Code from this article(You’ll can see different class names, but they are still the same), templates for this and video how to work with templates

6. Russian version of the article