Conversation
Created a annotation for use when a simple RecyclerViewAdapter, through Kombind. This will eliminate the need of creating the adapter boilerplate yourself. The annotation should be attached to a ObservableList<T> field
gregriggins36
left a comment
There was a problem hiding this comment.
Pretty slick, I never used javapoet or kotlinpoet.
Are you trying to just avoid creating the adapter class for a simple list of items? How do you specify methods in the handler?
app/src/main/java/com/umairjavid/kombindsample/ui/main/MainViewModel.kt
Outdated
Show resolved
Hide resolved
| if (it is VariableElement) | ||
| generateAdapterClass(it, layoutRes) | ||
| } | ||
| return false |
There was a problem hiding this comment.
We always return false?
There was a problem hiding this comment.
From my understanding , this method must always return false, if not other annotations/rounds will not be processed.
|
@gregriggins36 Yep! So in essence, in your viewmodel you can do @SimpleKombindAdapter(layoutRES) val items: MutableLiveArrayList() and the RecyclerViewAdapter will be autogenerated for you. Yea my first time using it as well lol :'D. Took abit of getting used to to say the least. You sort have to think of things differently because annotation processing happens before compilation. So you have no access to Objects instance, but instead Elements that make up the class itself. KotlinPoet simplifies a-lot of things, which would have been extremely tedious to do without. As for Handler, it is a constructor parameter of type any, so the user will need to pass in there own handler |
|
You're timing couldn't have been better, I was thinking of solving a problem at work by generating a class based off of an interface/base class. This looks pretty cool! |
…is to allow the user to specify a multi layout Recyclerview adapter
|
@ujavid Only thing is KotlinPoet, is a 3rd party api.But on the other hand the actually processor isn't shipped with the APK. Only the classes it generates :-D, so Cap1 should be good with it. The beauty of Kapt. Yea dude its pretty cool, once you past the complexity lol. So for Adapters that supports multiple types, the user just needs to do @SimpleKombindAdapter without specifying a layout res. This will generate an Abstract adapter, and the user just needs to override getLayout. Take a look at MainActivity and MainState. |
…ist<*>.Update build.gradle
app/build.gradle
Outdated
| dependencies { | ||
| implementation fileTree(include: ['*.jar'], dir: 'libs') | ||
| implementation project(':kombind') | ||
| compileOnly project(':anontation') |
| layoutManager = LinearLayoutManager(this@MainActivity) | ||
| adapter = SimpleItemAdapter(viewModel.state.items, viewModel) | ||
| .registerObserver(this@MainActivity) | ||
| adapter = object : Kombind_items_Adapter(viewModel.state.items, viewModel) { |
There was a problem hiding this comment.
how is the name Kombind_items_Adapter determined? why not make it KombindItemsAdapter?
There was a problem hiding this comment.
the actual name of the class is taken from the annotated variable name.
So if you have @SimpleAdapter val someVariable: MutableLiveArrayList
The generated class will be called Kombind_someVariable_Adapter. For ref look at AdapterProcessor.kt Line 60
processor/build.gradle
Outdated
| sourceCompatibility = "7" | ||
| targetCompatibility = "7" | ||
| buildscript { | ||
| ext.kotlin_version = '1.3.21' |
There was a problem hiding this comment.
why not use the one defined in the project build.gradle?
processor/build.gradle
Outdated
| mavenCentral() | ||
| } | ||
| dependencies { | ||
| classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" |
There was a problem hiding this comment.
isn't this defined in the build.gradle?
| implementation 'com.squareup:kotlinpoet:1.2.0' | ||
| } | ||
|
|
||
| sourceCompatibility = "7" |
There was a problem hiding this comment.
Yea I thought about it, I don't know if its useful for the sourceCompatibility to be the same as the JVM Target.. Wouldn't it be safer for it to be compatible with a lesser version?
| val kombindAdapterName = "KombindAdapter" | ||
| val viewHolder = "KombindAdapter.ViewHolder" | ||
| val fileName = element.simpleName | ||
| val className = "Kombind_${fileName}_Adapter" |
There was a problem hiding this comment.
in that case, can you change this? first it seems like it's not really fileName but elementName
second, could you do: "Kombind${elementName.capitalize()}Adapter"
There was a problem hiding this comment.
also how does this handle duplicate classes with the same name?
There was a problem hiding this comment.
Thats a good question lol. Perhaps I'll save the names in a set, and if the name has already been used I will add the enclosing class name as a namespace. Or have the user specify the name, with the annotation and error if the name has been used. What do you think?
There was a problem hiding this comment.
@ujavid Ok just updated this . Now the generated class will including the enclosing class name of the property.
for instance : In MainState.k there is @SimpleKombindAdapter val items = MutableLiveArrayList
This generated a class called, KombindItemsAdapter_MainState.
It shouldn't be possible to have duplicate names with that signature structure,
| val appPackageName = processingEnv.elementUtils.getPackageOf(element).simpleName.toString() | ||
| val kombindAdapterName = "KombindAdapter" | ||
| val viewHolder = "KombindAdapter.ViewHolder" | ||
| val fileName = element.simpleName |
2.) Remove redundant build.gradle kotlin dependency 3.) Update generated class name
|
@ujavid Just made a commit fixing the naming and the spelling |
processor/src/main/java/com/umairjavid/kombind/processor/AdapterProcessor.kt
Outdated
Show resolved
Hide resolved
…]_[VariableName]" This reverts commit f7f701a.
@gregriggins36 @ujavid, Im adding a code gen for generating a simple Kombind adapter. So @SimpleKombindAdapter(..layResId..) items: MutableLiveArrayList<*> Will generate a KombindAdapter class. The adapter class will be generated with the following signature
Kombind_[propertyName]_Adapter(items: MutableLiveArrayList, handler: Any) { ...} . For right now it can't support Multiple types. Will be cleaning up the code, and updating the sample project