In this post, you will see how to get any adapter class from your model class easily in less than a minute with incremental build and supporting KSP and Kapt.
Introduction
In Android Development, almost every project has one or more Adapter
classes to deal with a collection of views. Also, there are many different types of adapters such as RecyclerAdapter
, ListAdapter
, Paging2 Adapter
, Paging3 Adapter
, ArrayAdapter
, ExpandableListAdapter
. Sometimes, you need to create a complex Adapter
class, but most of the times, all you need is to bind your model class with a list item layout and provide some extra listeners and that's it, so why can’t we automate the process of creating those Adapter
classes?
Before talking about how we will automate it, let's first talk about what feature we want and what problems we want to avoid.
Let’s Start with the Features
- Declare how to bind data to views easily.
- Add listeners to any view or to the main list item layout view.
- Support some features like loading images with third party libraries like Picasso, Glide, COIL.
- Support default and custom names for the
Adapter
class. - Provide clear error messages if we made any mistakes.
What Problems Do We Want to Avoid by Using this Solution?
- Add any cost to the runtime
- Writing complex code to deal with this solution
- Slow build time
- Hard to learn
- Limitation
What is this Solution?
The solution is EasyAdapter
which is a new Android Annotation Processing library that can generate Adapter
classes based on your model class and your custom information in the compile time only.
How Does It Work?
EasyAdapter
has only two types of Annotations which are Adapters and Binds Annotations, the first type is used to annotate the model class to tell EasyAdapter
what type of adapter you want to generate from this model and what list item you want to use for example:
@ListAdapter("com.amrdeveloper.app", "list_item_model")
class Model
This example tells the library that you want to generate ListAdapter
for the Model
class and use R.layout.list_item_model
as a list item. You can also change the generated name for example.
@ListAdapter("com.amrdeveloper.app", "list_item_model", "ModelAdapter")
class Model
And in version 1.0.0, EasyAdapter
provides six Adapter
types which are:
ArrayAdapter
ListAdapter
RecyclerAdapter
PagedListAdapter
PagingDataAdapter
ExpandableListAdapter
You can also find the full documentation about them with examples on the documentation website.
The second annotation type is Bind Annotations and they used to bind or provide features.
For example, to tell EasyAdapter
that you want to use this string
field as a text for TextView
with id R.id.user_name
, you can use @BindText
.
@BindText("user_name") val name : String
and this code will generate a code to load the image with path imagePath
inside ImageView
class with id R.id.user_avatar
.
@BindImage(ImageLoader.PICASSO, "user_avatar")
val imagePath : String
You can also use @BindListener
annotation on the model class to generate listener for any view for example:
@BindListener(ListenerType.OnClick)
@BindListener(ListenerType.OnClick, "call_button")
...
class Model
EasyAdapter
now will generate 2 on click listener: the first one for the list item itself and the other for view with id R.id.call_button
:
In Version 1.0.0, 10 Bind Annotations which are:
BindText
BindImage
BindImageRes
BindBackgroundColor
BindBackgroundRes
BindAlpha
BindGif
BindVisibility
BindListener
BindExpandable
BindExpandableMap
And from version 1.0.2, we have also BindTextColor
and conditional binding feature.
You can also find the full documentation about them with examples on the documentation website.
Using EasyAdapter
is not hard as you can see and you can learn it easily in minutes.
But How Does EasyAdapter Really Work?
EasyAdapter
has support for 2 Annotation Processors Kapt (Kotlin Annotation Processing Tool) and KSP (Kotlin Symbol Processing) to walk in your source code and collect information from the annotations with simple type checking to make sure, for example, what @BindImage
annotate string field represents the image path, show error and warn messages if needed, and after we have all the required information, we used code generators that generate the result adapter class source code using kotlinpoet library from Square, then we write this source code in Adapter files inside the output directory :D. We try to make the generated code as optimized as possible, for example, we avoid calling mutable findViewById
with the same id. Instead of that, we have a ViewTable
class inspired from the SymbolTable concept to manage the declared variable and reuse them again.
This is just the first version, and everyone is welcome to help to improve this tool by suggesting features, reporting issues and contributing to the code base or documentation, everyone can add value.
Github Repository: AmrDeveloper/EasyAdapter
Website: EasyAdapter
You can find me on GitHub.
Enjoy programming 😋.
History
- 4th March, 2022: Initial version