Created
July 30, 2019 10:46
-
-
Save Holofox/bac89e9eb85e68e0e5d9894e73666790 to your computer and use it in GitHub Desktop.
DataBindingAdapter for RecyclerView (MVVM)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
abstract class DataBindingAdapter<T>( | |
private val variableId: Int, | |
diffCallback: DiffUtil.ItemCallback<T> | |
) : ListAdapter<T, DataBindingAdapter.DataBindingViewHolder<T>>(diffCallback) { | |
private var list: List<T>? = emptyList() | |
private lateinit var onItemViewClick: ((View, T, Int) -> Unit?) | |
private lateinit var clickableIds: IntArray | |
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DataBindingViewHolder<T> { | |
val layoutInflater = LayoutInflater.from(parent.context) | |
val binding = DataBindingUtil.inflate<ViewDataBinding>(layoutInflater, viewType, parent, false) | |
return DataBindingViewHolder(binding, variableId) | |
} | |
override fun onBindViewHolder(holder: DataBindingViewHolder<T>, position: Int) { | |
holder.apply { | |
bind(getItem(position)) | |
if (::onItemViewClick.isInitialized && ::clickableIds.isInitialized) { | |
val clickListener = View.OnClickListener { view -> | |
list?.get(holder.adapterPosition)?.let { | |
onItemViewClick.invoke(view, it, holder.adapterPosition) | |
} | |
} | |
for (clickableId in clickableIds) { | |
holder.itemView.findViewById<View>(clickableId)?.setOnClickListener(clickListener) | |
} | |
} | |
} | |
} | |
override fun submitList(list: List<T>?) { | |
super.submitList(list) | |
this.list = list | |
} | |
fun setOnItemViewClickListener( | |
onItemViewClick: (view: View, model: T, position: Int) -> Unit, | |
vararg ids: Int | |
) { | |
this.onItemViewClick = onItemViewClick | |
this.clickableIds = ids | |
} | |
class DataBindingViewHolder<T>( | |
private val binding: ViewDataBinding, | |
private val variableId: Int | |
) : RecyclerView.ViewHolder(binding.root) { | |
fun bind(item: T) { | |
binding.setVariable(variableId, item) | |
binding.executePendingBindings() | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<layout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto"> | |
<data> | |
<variable | |
name="postponedListModel" | |
type="ru.holofox.anicoubs.data.db.unitlocalized.vk.UnitSpecificVKWallMinimalEntry" /> | |
</data> | |
<com.google.android.material.card.MaterialCardView | |
android:id="@+id/cardView_postponed" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:minHeight="?listPreferredItemHeightLarge" | |
android:layout_margin="4dp" | |
app:cardCornerRadius="4dp"> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:minHeight="?listPreferredItemHeightLarge"> | |
<!-- ... --> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
</com.google.android.material.card.MaterialCardView> | |
</layout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PostponedAdapter : | |
DataBindingAdapter<UnitSpecificVKWallMinimalEntry>(BR.postponedListModel, DiffCallback()) { | |
class DiffCallback : DiffUtil.ItemCallback<UnitSpecificVKWallMinimalEntry>() { | |
override fun areItemsTheSame( | |
oldItem: UnitSpecificVKWallMinimalEntry, | |
newItem: UnitSpecificVKWallMinimalEntry | |
): Boolean = oldItem.id == newItem.id | |
override fun areContentsTheSame( | |
oldItem: UnitSpecificVKWallMinimalEntry, | |
newItem: UnitSpecificVKWallMinimalEntry | |
): Boolean = oldItem == newItem | |
} | |
override fun getItemViewType(position: Int) = R.layout.item_postponed | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PostponedListFragment : Fragment() { | |
... | |
private var viewModelAdapter: PostponedAdapter? = null | |
private val onItemMore: (View) -> Unit = { } | |
override fun onCreateView( | |
inflater: LayoutInflater, container: ViewGroup?, | |
savedInstanceState: Bundle?): View? { | |
binding = DataBindingUtil.inflate( | |
inflater, | |
R.layout.postponed_list_fragment, | |
container, | |
false | |
) | |
viewModelAdapter = PostponedListAdapter().apply { | |
setOnItemViewClickListener({view, model, position -> | |
when (view.id) { | |
R.id.cardView_postponed -> showPostponedDetail(view) | |
R.id.imageView_more -> onItemMore(view) | |
} | |
}, R.id.imageView_more, R.id.cardView_postponed) | |
} | |
binding.apply { | |
lifecycleOwner = viewLifecycleOwner | |
postponedViewModel = viewModel | |
recyclerView.adapter = viewModelAdapter | |
} | |
return binding.root | |
} | |
override fun onActivityCreated(savedInstanceState: Bundle?) { | |
super.onActivityCreated(savedInstanceState) | |
viewModel.wall.observe(viewLifecycleOwner, Observer { entries -> | |
entries?.let { | |
viewModelAdapter?.submitList(entries) | |
} | |
}) | |
} | |
private fun showPostponedDetail(view: View) { } | |
... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment