Skip to content

Comments

Add SimpleAdapter Annotation#8

Open
RobertKeazor wants to merge 11 commits intoujavid:masterfrom
RobertKeazor:develop
Open

Add SimpleAdapter Annotation#8
RobertKeazor wants to merge 11 commits intoujavid:masterfrom
RobertKeazor:develop

Conversation

@RobertKeazor
Copy link
Contributor

@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

rkeazor added 3 commits April 9, 2019 11:44
  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
Copy link
Contributor

@gregriggins36 gregriggins36 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

if (it is VariableElement)
generateAdapterClass(it, layoutRes)
}
return false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We always return false?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding , this method must always return false, if not other annotations/rounds will not be processed.

@RobertKeazor
Copy link
Contributor Author

RobertKeazor commented Apr 14, 2019

@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

@ujavid
Copy link
Owner

ujavid commented Apr 14, 2019

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
@RobertKeazor
Copy link
Contributor Author

RobertKeazor commented Apr 15, 2019

@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.

app/build.gradle Outdated
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation project(':kombind')
compileOnly project(':anontation')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

misspelled

layoutManager = LinearLayoutManager(this@MainActivity)
adapter = SimpleItemAdapter(viewModel.state.items, viewModel)
.registerObserver(this@MainActivity)
adapter = object : Kombind_items_Adapter(viewModel.state.items, viewModel) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is the name Kombind_items_Adapter determined? why not make it KombindItemsAdapter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

sourceCompatibility = "7"
targetCompatibility = "7"
buildscript {
ext.kotlin_version = '1.3.21'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use the one defined in the project build.gradle?

mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this defined in the build.gradle?

implementation 'com.squareup:kotlinpoet:1.2.0'
}

sourceCompatibility = "7"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not 8 as @gregriggins36 mentioned?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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"

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also how does this handle duplicate classes with the same name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to elementName

2.) Remove redundant build.gradle kotlin dependency
3.) Update generated class name
@RobertKeazor
Copy link
Contributor Author

@ujavid Just made a commit fixing the naming and the spelling

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants