Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Data binding tracking
inline fun <V : View, I> V.trackInstance(
newInstance: I?,
@IdRes instanceResId: Int,
onDetached: V.(I) -> Unit = {},
onAttached: V.(I) -> Unit = {}
) {
ListenerUtil.trackListener(this, newInstance, instanceResId).let { oldInstance ->
if (oldInstance !== newInstance) { // referential comparison
oldInstance?.let { onDetached(oldInstance) }
newInstance?.let { onAttached(newInstance) }
}
}
}
// trackInstance example with DefaultTimeBar from ExoPlayer:
// can't use kotlin Function1 as it's generic :'(
interface LongBindingConsumer {
fun invoke(value: Long)
}
// no inverse binding here as there's no way to get the position like SeekBar
@BindingAdapter(
"onScrubStart",
"onScrubMove",
"onScrubStop", requireAll = false
)
fun DefaultTimeBar.bind(
onScrubStart: LongBindingConsumer?,
onScrubMove: LongBindingConsumer?,
onScrubStop: LongBindingConsumer?
) {
trackInstance(
newInstance = if (onScrubStart != null || onScrubMove != null || onScrubStop != null) {
object : TimeBar.OnScrubListener {
override fun onScrubStart(timeBar: TimeBar?, position: Long) {
onScrubStart?.invoke(position)
}
override fun onScrubMove(timeBar: TimeBar?, position: Long) {
onScrubMove?.invoke(position)
}
override fun onScrubStop(timeBar: TimeBar?, position: Long, canceled: Boolean) {
onScrubStop?.invoke(position)
}
}
} else null,
instanceResId = R.id.timebar_on_scrub_listener, // create ID for everything you want to track
onDetached = { removeListener(it) },
onAttached = { addListener(it) }
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment