From 302d3351e9866b71b1e525c0e5ba883fe022ba5c Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sun, 20 Oct 2019 01:51:18 -0700 Subject: Update binding definitions --- .../fastadapter/viewbinding/BindingItem.kt | 91 ++++++++++------------ 1 file changed, 41 insertions(+), 50 deletions(-) diff --git a/fastadapter-viewbinding/src/main/kotlin/ca/allanwang/fastadapter/viewbinding/BindingItem.kt b/fastadapter-viewbinding/src/main/kotlin/ca/allanwang/fastadapter/viewbinding/BindingItem.kt index d1ae65f..d40be3d 100644 --- a/fastadapter-viewbinding/src/main/kotlin/ca/allanwang/fastadapter/viewbinding/BindingItem.kt +++ b/fastadapter-viewbinding/src/main/kotlin/ca/allanwang/fastadapter/viewbinding/BindingItem.kt @@ -31,65 +31,48 @@ interface VhModel { fun vh(): GenericItem } +/** + * Layout container. Should be implemented in a [BindingItem] companion. + */ interface BindingLayout { val layoutRes: Int - fun createBinding(context: Context, parent: ViewGroup?): Binding - fun Binding.bindView(holder: ViewHolder, payloads: MutableList) - fun Binding.unbindView(holder: ViewHolder) - - class ViewHolder(itemView: View, internal val layoutRes: Int) : - RecyclerView.ViewHolder(itemView) { - - /** - * Retrieves a binding. - * - * It is assumed that the binding is set on view holder creation, - * and that its type matches the supplied generic. - */ - fun getBinding(): T = getBinding(itemView) - } - - companion object { - fun setBinding(view: View, binding: Any) { - view.setTag(R.id.kau_view_binding_model, binding) - } - - @Suppress("UNCHECKED_CAST") - fun getBinding(view: View): T = view.getTag(R.id.kau_view_binding_model) as T - } } abstract class BindingItem(open val data: Any?) : - AbstractItem(), + AbstractItem(), BindingLayout { override val type: Int get() = layoutRes + abstract fun createBinding(context: Context, parent: ViewGroup?): Binding + override fun createView(ctx: Context, parent: ViewGroup?): View { val binding = createBinding(ctx, parent) - BindingLayout.setBinding(binding.root, binding) + setBinding(binding.root, binding) return binding.root } - final override fun bindView(holder: BindingLayout.ViewHolder, payloads: MutableList) { + final override fun bindView(holder: ViewHolder, payloads: MutableList) { super.bindView(holder, payloads) val binding = holder.getBinding() binding.bindView(holder, payloads) } - final override fun unbindView(holder: BindingLayout.ViewHolder) { + abstract fun Binding.bindView(holder: ViewHolder, payloads: MutableList) + + final override fun unbindView(holder: ViewHolder) { super.unbindView(holder) val binding = holder.getBinding() binding.unbindView(holder) } - override fun Binding.unbindView(holder: BindingLayout.ViewHolder) {} + open fun Binding.unbindView(holder: ViewHolder) {} - final override fun getViewHolder(v: View): BindingLayout.ViewHolder = - BindingLayout.ViewHolder(v, layoutRes) + final override fun getViewHolder(v: View): ViewHolder = + ViewHolder(v, layoutRes) - override fun failedToRecycle(holder: BindingLayout.ViewHolder): Boolean { + override fun failedToRecycle(holder: ViewHolder): Boolean { KL.e { "Failed to recycle" } return super.failedToRecycle(holder) } @@ -101,36 +84,44 @@ abstract class BindingItem(open val data: Any?) : } override fun hashCode(): Int = data.hashCode() + + class ViewHolder(itemView: View, internal val layoutRes: Int) : + RecyclerView.ViewHolder(itemView) { + + /** + * Retrieves a binding. + * + * It is assumed that the binding is set prior to this call, + * and that its type matches the supplied generic. + */ + fun getBinding(): T = getBinding(itemView) + } + + companion object { + fun setBinding(view: View, binding: Any) { + view.setTag(R.id.kau_view_binding_model, binding) + } + + @Suppress("UNCHECKED_CAST") + fun getBinding(view: View): T = view.getTag(R.id.kau_view_binding_model) as T + } } abstract class BindingClickEventHook>(val identifier: BindingLayout) : ClickEventHook() { private fun RecyclerView.ViewHolder.binding(): Binding? { - val holder = this as? BindingLayout.ViewHolder ?: return null + val holder = this as? BindingItem.ViewHolder ?: return null if (holder.layoutRes != identifier.layoutRes) { return null } return getBinding() } - /** - * All bound views must set the view root, which will be used to find the binding. - * We avoid attaching the binding directly - */ - private fun View.setRoot(root: View) { - setTag(R.id.kau_view_binding_root, root) - } - - private fun View.findBinding(): Binding { - val root = getTag(R.id.kau_view_binding_root) as View - return BindingLayout.getBinding(root) - } - final override fun onBind(viewHolder: RecyclerView.ViewHolder): View? { val binding = viewHolder.binding() ?: return super.onBind(viewHolder) val view = binding.onBind(viewHolder) ?: return super.onBind(viewHolder) - view.setRoot(binding.root) + BindingItem.setBinding(view, binding) return view } @@ -139,7 +130,7 @@ abstract class BindingClickEventHook? { val binding = viewHolder.binding() ?: return super.onBindMany(viewHolder) val views = binding.onBindMany(viewHolder) ?: return super.onBindMany(viewHolder) - views.forEach { it.setRoot(binding.root) } + views.forEach { BindingItem.setBinding(it, binding) } return views } @@ -147,8 +138,8 @@ abstract class BindingClickEventHook, item: Item) { - v.findBinding().onClick(v, position, fastAdapter, item) + BindingItem.getBinding(v).onClick(v, position, fastAdapter, item) } abstract fun Binding.onClick(v: View, position: Int, fastAdapter: FastAdapter, item: Item) -} +} \ No newline at end of file -- cgit v1.2.3