Generate your own RecyclerView.Adapter with blackjack and DataBinding

Bogdan Voiko
AndroidPub
Published in
2 min readAug 6, 2017

Aren’t you tired of creating RecyclerView.Adapters over and over again? It would seem that with DataBinding coming we’ll “write more code by writing less code”, but this Adapters “generating” seems like to be endless. So, why wouldn’t you generate your adapters with few annotations and even less lines of code?

How did I handle all this stuff before

Until now one of my best approach was this:

public class BindingViewHolder<T extends ViewDataBinding> extends RecyclerView.ViewHolder {     private T binding; 

public BindingViewHolder(T binding){
super(binding.getRoot());
this.binding = binding;
}
public T getBinding() { return binding; }
}

With this you basically can pass any DataBingingUtil.inflate(..) into this ViewHolder constructor and you’ll receive your fancy ViewHolder with DataBinding abilities.

What’s problem with this? Yes, really, you don’t need to create bunch of ViewHolders, but you still need to create bunch of Adapters, with onCreateViewHolder , onBindViewHolder and so on. And this is dramatic waste of time.

When all started

From past Google I/O I noticed one thing:

We love Annotations

So I thought, if Java and Android in part have power of annotation processing, why can’t I make something generate this endless code for me?

The solution

And with some time passed I came to this

@Adapter( 
dataSetType = @DataSetType(dataSetType = TestData.class),
useViews = { @ViewFor(dataClass = TestData.class, viewRes = R.layout.rv_item_test_adapter) },
map = {
@Bind(bindClass = TestData.class, bindMode = BindMode.variable, bindingResourceName = “testData”),
@Bind(bindClass = Void.class, bindMode = BindMode.method, bindingResourceName = “clickAdapter”, methodName = “myMethod”, methodCallMode = MethodCallMode.onClick)
}
)
public class TestAdapter { }

Isn’t it smaller than one that you’r writing each time? Definitely smaller that mine ones.

“But this is not RecyclerView.Adapter ” you’ll say. You’ll be right, but created TestAdapterGenerated definitely will.

What is it? I’ll show you.

Don’t worry, ViewTypeEnum isn’t something internal, it’s enum generated for each RecyclerView.Adapter to map view types with data. You can see it live when you’ll try it by your own.

All you need to do now it’s simply

TestAdapterGenerated adapter = new TestAdapterGenerated() {
@Override
public Void myMethod(int position, BindingViewHolder holder, Object object) {
// DO SOME FANCY STUFF ONCLICK
return null;
}
};
recyclerView.setAdapter(adapter);
adapter.setData(...);
// OR
yourBinding.setData(data); // where "data" is a list, your XML contains variable "data" of type List and your RecyclerView have "app:src="@{data}"" attribute.

Isn’t it cool, ha?

To try it, just paste this in your modules build.gradle file

compile 'com.ekalips:adapter-annotation:0.1.1'
annotationProcessor 'com.ekalips:adapter-processor:0.1.1'

And this to your projects build.gradle

maven {
url "http://dl.bintray.com/ekalips/Bapter"
}

Just be sure, that DataBinding is enabled in your project.

For additional info and feedback leaving visit my GitHub project’s page

--

--