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
123
|
/*
* 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<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
)
return binding.root
}
fun getBinding(holder: ViewHolder): Binding? =
DataBindingUtil.getBinding<Binding>(holder.itemView)
final override fun bindView(holder: ViewHolder, payloads: MutableList<Any>) {
super.bindView(holder, payloads)
val binding = getBinding(holder) ?: return
binding.bindView(holder, payloads)
binding.executePendingBindings()
}
abstract fun Binding.bindView(holder: ViewHolder, payloads: MutableList<Any>)
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 {
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<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)
}
|