aboutsummaryrefslogtreecommitdiff
path: root/fastadapter-databinding/src/main/kotlin/ca/allanwang/fastadapter/databinding/BindingItem.kt
blob: e52838b5650cc3488be5a5356001ac1b6cef9aa9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package ca.allanwang.fastadapter.databinding


import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.gitdroid.logger.L
import ca.allanwang.gitdroid.views.BR
import com.bumptech.glide.Glide
import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.items.AbstractItem
import com.mikepenz.fastadapter.listeners.ClickEventHook

typealias GenericBindingItem = BindingItem<*>

abstract class BindingItem<Binding : ViewDataBinding>(open val data: Any?) : AbstractItem<BindingItem.ViewHolder>(),
    BindingLayout<Binding> {

    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,
            null
        )
        return binding.root
    }

    final override fun bindView(holder: ViewHolder, payloads: MutableList<Any>) {
        super.bindView(holder, payloads)
        val binding = DataBindingUtil.getBinding<Binding>(holder.itemView) ?: return
        binding.bindView(holder, payloads)
        binding.executePendingBindings()
    }

    open fun Binding.bindView(holder: ViewHolder, payloads: MutableList<Any>) {
        setVariable(BR.model, data)
    }

    final override fun unbindView(holder: ViewHolder) {
        super.unbindView(holder)
        val binding = DataBindingUtil.getBinding<Binding>(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 {
        L.e { "Failed to recycle" }
        return super.failedToRecycle(holder)
    }

    companion object {
        @JvmStatic
        protected fun unbindGlide(vararg imageView: ImageView) {
            if (imageView.isEmpty()) {
                return
            }
            val manager = Glide.with(imageView.first().context)
            imageView.forEach { manager.clear(it) }
        }

        @JvmStatic
        protected fun unbind(vararg imageView: ImageView) {
            imageView.forEach { it.setImageDrawable(null) }
        }

        @JvmStatic
        protected fun unbind(vararg textView: TextView) {
            textView.forEach { it.text = null }
        }
    }

    class ViewHolder(itemView: View, internal val layoutRes: Int) : RecyclerView.ViewHolder(itemView)

}

interface BindingLayout<Binding : ViewDataBinding> {
    val layoutRes: Int
}


abstract class BindingClickEventHook<Binding : ViewDataBinding, Item : BindingItem<Binding>>(val identifier: BindingLayout<Binding>) :
    ClickEventHook<Item>() {

    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<View>? =
        viewHolder.binding()?.onBindMany(viewHolder) ?: super.onBindMany(viewHolder)

    open fun Binding.onBindMany(viewHolder: RecyclerView.ViewHolder): List<View>? = super.onBindMany(viewHolder)

    final override fun onClick(v: View, position: Int, fastAdapter: FastAdapter<Item>, 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: Item)
}