Is LastAdapter ending RecyclerView adapter and ViewHolder?

Almost every single app needs to show some collection of elements on the screen. In Android, the most efficient way to do it is using RecyclerView, a widget that can handle how the views representing those items are displayed on the screen. RecyclerView uses an adapter that tells which element from the collection is going to be shown on the screen at a certain position, which view is going to use and which views can be recycled.

Creating new views is a very expensive operation in Android and that’s the reason why we use ViewHolders. They allow us to recycle the views going outside the screen when we scroll and reuse them for the items that become visible again.

The ideas behind RecyclerView are simple and effective, but there’s one problem: you need to write an adapter for every collection of items you want to show, and a ViewHolder for every type of item your list can show.

Unless you’re trying to do something more complex like sticky headers or expandable views, the process of writing adapters and ViewHolders is going to be very repetitive. You need to implement methods like getItemCount() returning the number of elements in your collection. Isn’t it obvious that it should be the size of the collection? Usually, the only interesting thing is the way one item is bound to a ViewHolder and thus to its view. And actually, it isn’t so interesting: it probably only sets some strings into TextViews, uses URLs to load images into ImageViews and so on… Exactly the kind of things the Data Binding library does directly in the layout XML.

LastAdapter = RecyclerView + ViewHolder

So why end up writing a whole new adapter every time you want to show a collection of items? Wouldn’t it be cool to simply specify the list of elements you want to show, which item type will be represented by which layout and then use Data Binding to bind every item to its view? Well, that’s what I think and that’s why I’ve made a library that avoids me having to write adapters over and over again.

Features of LastAdapter:

  • Based on Android Data Binding
  • Written in Kotlin
  • No need to write the adapter
  • No need to write the viewholders
  • No need to modify your model classes
  • No need to notify the adapter when data set changes
  • Supports multiple item view types
  • Optional Callbacks/Listeners
  • Very fast — no reflection
  • Super easy API
  • Tiny size: 26 KB
  • Minimum Android SDK: 9

Setup

Gradle

// apply plugin: 'kotlin-kapt' // this line only for Kotlin projects

android {
    ...
    dataBinding.enabled true 
}

dependencies {
    compile 'com.github.nitrico.lastadapter:lastadapter:2.2.2'
    // kapt 'com.android.databinding:compiler:GRADLE_PLUGIN_VERSION' // this line only for Kotlin projects
}

Usage

Create your item layouts with <layout> as root:

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable name="item" type="com.github.nitrico.lastadapterproject.item.Header"/>
    </data>
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@{item.text}"/>
        
</layout>

It is important for all the item types to have the same variable name, in this case “item”. This name is passed to the adapter builder as BR.variableName, in this case BR.item:

// Java
new LastAdapter(listOfItems, BR.item)
           .map(Header.class, R.layout.item_header)
           .map(Point.class, R.layout.item_point)
           .into(recyclerView);
// Kotlin
LastAdapter(listOfItems, BR.item)
           .map<Header>(R.layout.item_header)
           .map<Point>(R.layout.item_point)
           .into(recyclerView)

The list of items can be an ObservableList if you want to get the adapter automatically updated when its content changes, or a simple List if you don’t need to use this feature.

LayoutHandler

The LayoutHandler interface allows you to use different layouts based on more complex criteria. Its one single method receives the item and the position and returns the layout resource id.

// Java sample
new LastAdapter(listOfItems, BR.item)
           .handler(typeHandler)
           .into(recyclerView);

private LayoutHandler typeHandler = new LayoutHandler() {
    @Override public int getItemLayout(@NotNull Object item, int position) {
        if (item instanceof Header) {
            return (position == 0) ? R.layout.item_header_first : R.layout.item_header;
        } else {
            return R.layout.item_point;
        }
    }
};
// Kotlin sample
LastAdapter(listOfItems, BR.item).layout { item, position ->
    when (item) {
        is Header -> if (position == 0) R.layout.item_header_first else R.layout.item_header
        else -> R.layout.item_point 
    }
}.into(recyclerView)

Download this library:

Conclusion

There’s no need to waste your time writing adapters and ViewHolders unless you are trying to do something truly unique!

Thank you for reading, I hope you enjoyed. So please comment us!!

By Tell Me How

It is a technology blog and admin has excellent experience in programming from 5+ year. You can contact us at ceo.tellmehow@gmail.com

Share your thoughts

Leave a Reply

Loading Facebook Comments ...
Loading Disqus Comments ...