/* * Copyright 2019 Allan Wang * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ca.allanwang.fastadapter.databinding import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.databinding.DataBindingUtil import androidx.databinding.ViewDataBinding import androidx.recyclerview.widget.RecyclerView import ca.allanwang.kau.logging.KL import com.mikepenz.fastadapter.FastAdapter import com.mikepenz.fastadapter.GenericItem import com.mikepenz.fastadapter.items.AbstractItem import com.mikepenz.fastadapter.listeners.ClickEventHook interface VhModel { fun vh(): GenericItem } abstract class BindingItem(open val data: Any?) : AbstractItem(), BindingLayout { override val type: Int get() = layoutRes override fun createView(ctx: Context, parent: ViewGroup?): View { val binding: ViewDataBinding = DataBindingUtil.inflate( LayoutInflater.from(ctx), layoutRes, parent, false ) return binding.root } fun getBinding(holder: ViewHolder): Binding? = DataBindingUtil.getBinding(holder.itemView) final override fun bindView(holder: ViewHolder, payloads: MutableList) { super.bindView(holder, payloads) val binding = getBinding(holder) ?: return binding.bindView(holder, payloads) binding.executePendingBindings() } abstract fun Binding.bindView(holder: ViewHolder, payloads: MutableList) final override fun unbindView(holder: ViewHolder) { super.unbindView(holder) val binding = DataBindingUtil.getBinding(holder.itemView) ?: return binding.unbindView(holder) binding.unbind() } open fun Binding.unbindView(holder: ViewHolder) {} final override fun getViewHolder(v: View): ViewHolder = ViewHolder(v, layoutRes) override fun failedToRecycle(holder: ViewHolder): Boolean { KL.e { "Failed to recycle" } return super.failedToRecycle(holder) } override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is BindingItem<*>) return false return identifier == other.identifier && data == other.data } override fun hashCode(): Int = data.hashCode() class ViewHolder(itemView: View, internal val layoutRes: Int) : RecyclerView.ViewHolder(itemView) } interface BindingLayout { val layoutRes: Int } abstract class BindingClickEventHook>(val identifier: BindingLayout) : ClickEventHook() { private fun RecyclerView.ViewHolder.binding(): Binding? { val holder = this as? BindingItem.ViewHolder ?: return null if (holder.layoutRes != identifier.layoutRes) { return null } return DataBindingUtil.getBinding(itemView) } final override fun onBind(viewHolder: RecyclerView.ViewHolder): View? = viewHolder.binding()?.onBind(viewHolder) ?: super.onBind(viewHolder) open fun Binding.onBind(viewHolder: RecyclerView.ViewHolder): View? = super.onBind(viewHolder) final override fun onBindMany(viewHolder: RecyclerView.ViewHolder): List? = viewHolder.binding()?.onBindMany(viewHolder) ?: super.onBindMany(viewHolder) open fun Binding.onBindMany(viewHolder: RecyclerView.ViewHolder): List? = super.onBindMany(viewHolder) final override fun onClick(v: View, position: Int, fastAdapter: FastAdapter, item: Item) { val binding: Binding = DataBindingUtil.findBinding(v) ?: return binding.onClick(v, position, fastAdapter, item) } abstract fun Binding.onClick(v: View, position: Int, fastAdapter: FastAdapter, item: Item) }