ViewModelAdapter is a project that apply MVVM pattern for RecyclerView.Adapter in Android.
With setup of Jitpack first, than add dependency in your build.gradle
implementation 'com.github.carousell:ViewModelAdapter:0.2'
We want to make Activity
/Fragment
to be pure container and delegate the functionality to elements inside RecyclerView
to fulfill clean and scaleable architecture.
We use ViewModel as the data source of RecyclerView, and generate corresponding ViewHolder/View that will bind with the ViewModel and observe change or execute actions.
-
Create a list of
ViewModels
that extendsItemViewModel
that represent the different items that will be displayed into theRecyclerView
. The following methods should be implemented:- getKey: Provide a unique key to the ViewModel.
- compare: Compare different
ViewModel
and return if they are identical.
Example:
class TextViewModel(private val item: TextItem) : ItemViewModel() { override fun getKey(): String { return item.key } override fun compare(viewModel: ItemViewModel): Boolean { if (viewModel is TextViewModel) { return viewModel.text == text } return false } }
-
Create a list of
ViewHolders
that extendsViewModelHolder
to interact with your correspondingViewModel
. The following methods should be implemented:- onBind: Subscribe to the data sources (LiveData, RxJava, etc) provided by your ViewModel.
- onUnbind: Unsubscribe to the data sources (LiveData, RxJava, etc) provided by your ViewModel.
Example:
class TextHolder(itemView: View, private val lifecycleOwner: LifecycleOwner) : ViewModelHolder<TextViewModel>(itemView), Observer<String> { override fun onBind(viewModel: TextViewModel) { viewModel.liveData().observe(lifecycleOwner, this) } override fun onUnbind(viewModel: TextViewModel) { viewModel.liveData().removeObserver(this) } override fun onChanged(string: String?) { itemView.text.text = string } }
-
Create adapter extends
ViewModelAdapter
which will handle theViewModel
binding for you. The only method need to implement:- onCreateViewHolder: Create the corresponding
ItemViewModel
via different modelType.
Example:
override fun onCreateViewHolder( parent: ViewGroup, modelType: Class<out ItemViewModel> ): ViewModelHolder<out ItemViewModel> { val layoutInflater = LayoutInflater.from(parent.context) return when (modelType) { TextViewModel::class.java -> TextHolder( layoutInflater.inflate(R.layout.adapter_text, parent, false), lifecycleOwner ) EditViewModel::class.java -> EditHolder( layoutInflater.inflate(R.layout.adapter_edit, parent, false) ) else -> throw RuntimeException("Not support") } }
- onCreateViewHolder: Create the corresponding
Go to ./app
module for more information.
Thank you for being interested in contributing to this project. Check out the CONTRIBUTING document for more info.
ViewModelAdapter is created and maintained by Carousell. Help us improve this project! We'd love the feedback from you.
We're hiring! Find out more at http://careers.carousell.com/
ViewModelAdapter is released under Apache License 2.0. See LICENSE for more details.