BindsAdapter is an Android library to help you create and maintain Adapter class easier via ksp( Kotlin Symbol Processing).

Overview

BindsAdapter

CircleCI Jitpack

BindsAdapter is an Android library to help you create and maintain Adapter class easier via ksp( Kotlin Symbol Processing).

Installation

First, add jitpack as one of the repositories in your project.

repositories {
    maven { url 'https://jitpack.io' }
}

And then apply the ksp plugin in your module where you need the factory be generated.

plugins {
    id 'com.google.devtools.ksp' version '1.7.0-1.0.6'
}

And then declare the dependency. Do noted that for the processor dependency, it requires ksp not kapt

implementation 'com.github.Jintin.BindsAdapter:annotation:{latest-version}'
ksp 'com.github.Jintin.BindsAdapter:processor:{latest-version}'

Lastly, the generated file will be located inside build/generated/ksp/, but your IDE might not able to identify it. In such case you can add it manually like below:

sourceSets {
    main {
        java {
            srcDir "${buildDir.absolutePath}/generated/ksp/"
        }
    }
}

Usage

Adapter

First, create a abstract ListAdapter with annotation @BindAdapter and link all the associate ViewHolder into it.

@BindAdapter([MyViewHolder1::class, MyViewHolder2::class])
abstract class MyAdapter(
    diffCallback: DiffUtil.ItemCallback<String>
) : ListAdapter<String, RecyclerView.ViewHolder>(diffCallback)

Note: ListAdapter is a must now, but it doesn't mean we can't support general Adapter in the future.

ViewHolder

And then, create all your ViewHolder and label @BindFunction to the function you want to be called when onBindViewHolder is called from Adapter.

class MyViewHolder1(
    val binding: AdapterHolder1Binding,
) : RecyclerView.ViewHolder(binding.root) {

    @BindFunction
    fun bindHolder1(data: String) {
        binding.text.text = data
    }
}

Note: Using ViewBinding is a must too and there's no other options for now but we do recommend to use it.

ViewTypes

After successfully compile, the MyAdapterImpl.kt will auto-generated with the all the viewType you need like below:

public class MyAdapterImpl(
    diffCallback: DiffUtil.ItemCallback<String>,
) : MyAdapter(diffCallback) {

    public companion object {
        public const val TYPE_MY_VIEW_HOLDER1: Int = 0

        public const val TYPE_MY_VIEW_HOLDER2: Int = 1
    }
}

Note: The value and order will be the same as you declared in @BindAdapter

And you can go back to the abstract Adapter to write getItemViewType if you have multi-viewType like below:

@BindAdapter([MyViewHolder1::class, MyViewHolder2::class])
abstract class MyAdapter(
    diffCallback: DiffUtil.ItemCallback<String>,
) : ListAdapter<String, RecyclerView.ViewHolder>(diffCallback) {

    override fun getItemViewType(position: Int): Int {
        return if (position % 2 == 0) {
            MyAdapterImpl.TYPE_MY_VIEW_HOLDER1
        } else {
            MyAdapterImpl.TYPE_MY_VIEW_HOLDER2
        }
    }
}

Parameter

In real world you might want to pass value from Adapter to ViewHolder. If you want to achieve this just label the parameter with the same Annotation from both side than we will help you to link them together. For Adapter, please add parameter in constructor. For ViewHolder, you can choose either constructor or the bind function which has @BindFunction.

@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class BindListener

@BindAdapter([MyViewHolder1::class, MyViewHolder2::class])
abstract class MyAdapter(
    diffCallback: DiffUtil.ItemCallback<String>,
    @BindListener val listener: (String) -> Unit,
) : ListAdapter<String, RecyclerView.ViewHolder>(diffCallback)

class MyViewHolder1(
    private val binding: AdapterHolder1Binding,
) : RecyclerView.ViewHolder(binding.root) {

    @BindFunction
    fun bindHolder1(data: String, @BindListener listener: (String) -> Unit) {
        binding.text.text = data
        binding.root.setOnClickListener { listener.invoke(data) }
    }
}

class MyViewHolder2(
    @BindListener val listener: (String) -> Unit,
    val binding: AdapterHolder2Binding,
) : RecyclerView.ViewHolder(binding.root) {

    @BindFunction
    fun bindHolder2(String, data: String) {
        binding.text.text = data
        binding.root.setOnClickListener { listener.invoke(data) }
    }
}

Note: There's not type restriction for the parameter and we also don't force them to be equal, but it will compile fail if it can't match.

Contributing

It's an interesting project to me and it's also in very early stage for now. Any thing can be changed and any kind of contribution or participate is welcome. Feel free to ask questions or report bugs. And we're also welcome you to create new pr if you have any idea!!

License

The module is available as open source under the terms of the MIT License.

You might also like...
🎲 Kotlin Symbol Processor to auto-generate extensive sealed classes and interfaces for Android and Kotlin.
🎲 Kotlin Symbol Processor to auto-generate extensive sealed classes and interfaces for Android and Kotlin.

SealedX 🎲 Kotlin Symbol Processor to auto-generate extensive sealed classes and interfaces for Android and Kotlin. Why SealedX? SealedX generates ext

SeatBookView is an Android Studio Library that helps to make it easier to create Bus, Train, Cinema Theater Seat UI and all functionalities are given.
SeatBookView is an Android Studio Library that helps to make it easier to create Bus, Train, Cinema Theater Seat UI and all functionalities are given.

SeatBookView SeatBookView is an Android Studio Library that helps to make it easier to create Bus 🚍 , Train 🚉 , Cinema Theater Seat UI and all funct

A Kotlin Symbol Processor to list sealed object instances.

Sealed Object Instances A Kotlin Symbol Processor to list sealed object instances. Usage Let's say you have a similar structure of sealed classes (or

DSU-Sideloader - A simple app made to help users easily install GSIs via DSU's Android feature
DSU-Sideloader - A simple app made to help users easily install GSIs via DSU's Android feature

DSU Sideloader A simple app made to help users easily install GSIs via DSU's And

Ksp-di-library - Small library for DI in KMM apps

DI-KSP Small library for DI in KMM apps. Uses KSP for processing DI annotations:

KSP-based library that generates lists from your annotation usages

ListGen, Generate Lists From Functions That Have @Listed Annotations! Welcome to ListGen! ListGen is a KSP-based library that can generate lists (and

A ksp library to automatically generate navigation functions for jetpack compose.
A ksp library to automatically generate navigation functions for jetpack compose.

Compose/Navigation/Generator ⚠️ This library is still under development and not considered stable! Content Introduction Usage Example: Single destinat

KSP extension for the kotlin-maven-plugin

kotlin-maven-symbol-processing Extension for the kotlin-maven-plugin to support Kotlin Symbol Processing (KSP). Usage To use this extension, add the d

Image Processing Engine with GUI
Image Processing Engine with GUI

Image Processing Engine with GUI Imperial College London Department of Computing Third Year Software Engineer Group Project Supervisor: Dr. Pancham Sh

Owner
Jintin
Android GDE, husband and dad. Love to build interesting things to make life easier.
Jintin
Exploring Kotlin Symbol Processing - KSP. This is just an experiment.

KSP example Exploring Kotlin Symbol Processing - KSP. This is just an experiment. Project contains 2 modules Processing Example Processing module is t

Merab Tato Kutalia 12 Aug 23, 2022
Kotlin Symbol Processing (KSP) sample project

Kotlin Symbol Processing (KSP) Sample Project Sample annotation processor created with Kotlin Symbol Processing (KSP) API. The repository supplements

Pavlo Stavytskyi 33 Dec 23, 2022
glide's ksp compiler ,use kotlin symbol processor

glide-ksp glide's ksp compiler ,use kotlin symbol processor requirements library version kotlin >= 1.6.10 ksp 1.6.10-1.0.2 usage add jitpack repositor

Mistletoe 24 Oct 17, 2022
Kotlin Symbol Processor library to create Mutable and Immutable variants of objects.

implier Kotlin Symbol Processor plugin to create Mutable and Immutable variants of objects. Examples @ImmutableImpl @MutableImpl public interface Samp

Vadim Yaroschuk 14 Nov 8, 2022
Simplify the processing of sealed class/interface

shiirudo Generates DSL to simplify processing branching by when expressions in sealed class/interface. Setup Refer to the KSP quickstart guide to make

KeitaTakahashi 2 Nov 1, 2022
Data structures in kotlin that maintain order

Ordered Data Structures I came from C++ and fell in love with kotlin. I used the C++ stdlib a lot. I have really been wanted to reach for map and unor

Kyle McBurnett 0 Nov 1, 2021
Scaloid makes your Android code easy to understand and maintain.

Simpler Android Scaloid is a library that simplifies your Android code. It makes your code easy to understand and maintain by leveraging Scala languag

Sung-Ho Lee 2.1k Dec 27, 2022
Ktorm KSP extension to help generate boilerplate code.

Ktorm KSP extension to help generate boilerplate code. It can automatically generate Table objects through entity classes, while making entities defined by data classes easier to use, and supports custom extension code generation logic.

KTORM.ORG 24 Dec 30, 2022
Kotlin extension function provides a facility to "add" methods to class without inheriting a class or using any type of design pattern

What is Kotlin Extension Function ? Kotlin extension function provides a facility to "add" methods to class without inheriting a class or using any ty

mohsen 21 Dec 3, 2022
A deep learning based mobile application for the multi-class classification of pneumonia into three categories via Chest X-rays

PneumoniaClassifier A deep learning based mobile application for the multi-class classification of pneumonia into three categories via Chest X-rays. W

Timilehin Aregbesola 2 Dec 15, 2021