Overview
Konveyor is a tiny library which intends to battle RecyclerView.Adapter
Hell by introducing "Composition over inheritance" approach when dealing with RecyclerView adapters. While making your Adapter related logic testable by providing abstraction layer over its logic, it will make you forget all of the ViewType hassle all together.
Contents
Installation
Gradle
Step 1. Add this in your root build.gradle
allprojects {
repositories {
maven {
url 'https://jitpack.io'
}
}
}
Step 2. Add the dependency
dependencies {
compile 'com.github.avito-tech:Konveyor:VERSION'
}
If you like to stay on the bleeding edge, or use certain commit as your dependency, you can use the short commit hash or anyBranch-SNAPSHOT
as the version
Maven
<dependency>
<groupId>com.github.avito-tech</groupId>
<artifactId>Konveyor</artifactId>
<version>VERSION</version> </dependency>
Structure
Konveyor introduces set of key abstractions to extract knowledge about ids and view types away from RecyclerView.Adapter
, thus, making all of the associated logic easily extensible and testable.
Item
Item is an interface that represents data associated with a certain ViewType
:
class Dog(override val id: Long) : Item
id — identifier, that RecyclerView.Adapter
will use in its methods.
ItemView
ItemView is an abstraction over RecyclerView.ViewHolder
interface DogView : ItemView {
fun setName(name: String)
}
class DogViewHolder(view: View): BaseViewHolder(view), DogView {
private val name = view.findViewById(R.id.name) as TextView
override fun setName(name: String) {
this.name.text = name
}
}
Methods Overview
onUnbind()
is called whenever RecyclerView.Adapter
calls onViewRecycled()
method for this ItemView. You can override this method in case you need, for example, unsubscribe from listeners or release some resources associated with this ViewHolder
.
ItemPresenter
ItemPresenter connects Item
and its view. Essentially, your implementation of the interface should contain everything you would normally do in onBindViewHolder()
method of RecyclerView.Adapter
class DogPresenter: ItemPresenter<DogItemView, Dog> {
override fun bindView(view: DogView, item: Dog, position: Int) {
view.setName(item.name)
}
}
ItemBlueprint
ItemBlueprint is a key entity that ties together Android world with our abstractions
class DogBlueprint(override val presenter: ItemPresenter<DogView, Dog>)
: ItemBlueprint<DogView, Dog> {
override val viewHolderProvider = ViewHolderBuilder.ViewHolderProvider(
layoutId = R.layout.dog_item,
creator = {
_, view -> DogViewHolder(view)
}
)
override fun isRelevantItem(item: Item): Boolean = item is Dog
}
Methods Overview
- presenter — presenter associated with this view and data.
- viewHolderProvider — class to create associated
RecyclerView.ViewHolder
- isRelevantItem(item: Item) — you have to override this method to build connection between given
Item
and itsItemBlueprint
. Please mind, in the list of registeredItemBlueprint
s every check has to be unique. If multiple registeredItemBlueprint
s respondtrue
to a givenItem
,ViewTypeCollisionException
will be thrown.
ItemBlueprint
AdapterPresenter is an abstraction over RecyclerView.Adapter
, that we can easily use in our unit tests. Current library provides default implementation for this interface - SimpleAdapterPresenter
, this will satisfy 99.9% of your needs, unless you need something exotic.
Example
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val recycler = view.findViewById(R.id.recycler) as RecyclerView
val binder = ItemBinder.Builder()
.registerItem(createDogBlueprint())
.registerItem(createCatBlueprint())
val adapterPresenter = SimpleAdapterPresenter(binder, binder)
recycler.adapter = SimpleRecyclerAdapter(adapterPresenter, binder)
}
In most cases SimpleRecyclerAdapter
, provided by this library will satisfy your needs.
This way you don't have to think about providing unique ViewType
s for your data, as ItemBinder
will handle this for you.
Author
Philip Uvarov ([email protected])
License
MIT