gilgoldzweig / Gencycler

Gencycler is the fastest way to write RecyclerView adapters

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

GencyclerRecyclerAdapter.elements breaks encapsualtion

consp1racy opened this issue · comments

Current behavior

Currently, elements is var and mutable and public, allowing consumers to bypass the adapter API and completely break it. And new developers especially tend to work with the original ArrayList and then get confused when the RecyclerView doesn't update automatically.

abstract class GencyclerRecyclerAdapter<T : GencyclerModel, VH : GencyclerHolder>(
	var elements: MutableList<T> = ArrayList(),
) : RecyclerView.Adapter<VH>() {

Expected behavior

elements should be private val, so only the adapter can access it and consumers can change it only through the adapter's public API.

abstract class GencyclerRecyclerAdapter<T : GencyclerModel, VH : GencyclerHolder>(
) : RecyclerView.Adapter<VH>() {

    private val elements: MutableList<T> = ArrayList(),

    constructor(elements: List<T>): this() {
        // Make a private copy.
        this.elements.addAll(elements)
    }

I'm not sure about this part. I had cases where sometimes I needed to execute a few actions before I call notify.

Could you give a concrete use case?

There was a case that I needed to add multiple elements but I couldn't use addAll because I received the data as a stream one by one but the UI only needed to be updated after x amount of items.

I used the elements to add the items one by one and after the x amount of items I called notifyItemRangeInserted

The views wouldn't match the elements. The element count wouldn't match the expected state in recycler view and it would crash. Just because the user was scrolling around while all this is happening.

So, you can't alter the adapters data set without letting everybody know there were changes. You can't hope to "fix" some sort of shitty inappropriate upstream API in the adapter. What can be done?

UI only needed to be updated after x amount of items

Alright then, first collect X items and then use addAll. In RxJava2 you would use the buffer operator.

This is doable without breaking encapsulation. In fact, that's a huge red flag that something else (the data source in this case) isn't just right.

Okay, I see your point.