This is one of series of Simple Android Architecture. and you can check sample code there.

this article introduces simple way to use RecyclerView

when we use RecyclerView, we do the below

  1. create a classe extends RecyclerView.Adapter
    overrides getItemViewType(), onCreateViewHolder(), onBindViewHolder()
  2. create a class extends RecyclerView.ViewHolder, bind data into view
  3. set Adapter to RecyclerView

But, design only require only two of the below

  • list data
  • item’s layout

The below is the sample of them for explaining.

Suggestion

I suggest the below

You don’t need to implement RecyclerView.Adapter and much of boilerplate codes
Just add 2 line. itemList, itemLayoutId. That’s it

Even you don’t need to remember the attributes’ name. Android Studio suggest them.

If you are curious how it works. please checkout the library and check. it’s mentioned in the end of this article

Limitation

but, There are some limitation in the approach above if requirement is little more complicated

  1. If Good performance on drawing items is required.
  2. If LiveData is required.
  3. If several viewType is reuiqred
  4. Paging by api

How to cover the limitation

I believe that if requirement is simple, code also should be simple. if requirement is complicated, code also get little bit complicated. but still should minimize the boilerplate code with reasonable structure and also should be readable.

  1. If Good performance on drawing items is required.
    use DiffUtil.ItemCallback to let adapter knows that when invalidating ui is required.

DiffUtil.ItemCallback is abstract class. so, instead of it, let the item class implements DiffComparable which is custom interface of DiffUtil.ItemCallback.

Mostly you have to define the item’s class, in order to handle event like click. so, I think It’s ignorable boiler plate code to define item view model class(in the example, SimpleComparableListItemViewModel). and just implements DiffComparable, and mention if items are same or item’s contents are same.

After that, change itemList to itemListComparable. from Android Studio suggestion.

That’s it, you can cover performance issue

2. If LiveData is required

the library use data-binding library to bind item’s data to item’s layout.

but when RecyclerView.Adapter is created, the Adapter doesn’t know lifecycle of Fragment or Activity. so, when LiveData’s value is changed, value is not reflected on view.

with @BindingAdapter, It’s not possible for view to know fragment or activity.

so, I suggest the below

instead of using BindingAdapter, create adapter by bindData() extension function and set viewLifecyclerOwner to let adater to know it.

3. If several viewType is reuiqred

actually, I recommend to item’s layout include all view type’s layout and control each view type by visibility.

as I don’t recommend. I don’t provide sample, but just short explanation.

object: BaseRecyclerViewAdapter<Any>() {
    override fun getItemLayoutId(position: Int): Int {
        getLayoutId(getViewType(position))
    }
}
fun getViewType(position: Int): Int { /*todo*/ }
fun getLayoutId(viewType: Int): Int { /*todo*/ }

4. Paging by api

Without Jetpack Paging library, it’s complicated to implement paging.
but with Paging library, still it’s complicated to study and memorize and use the library.

so, I provide BaseNetworkDataSourceFactory to use it without understanding and memorizing Paging library

If you implemented BaseNetworkDataSourceFactory, just use same way with previous way.

Conclusion

I provide the sample here

you can run sample application and see the code in the package of kim.jeonghyeon.sample.list

I think the code satisfies MVVM and OOP, but if you have find any problem or suggestion. Kindly let me know to improve it.

Happy coding :)