Skip to content

Instantly share code, notes, and snippets.

@nsk-mironov
Created April 11, 2016 13:38
Show Gist options
  • Save nsk-mironov/78ccae01c3f8797adffeaeb4cb37794c to your computer and use it in GitHub Desktop.
Save nsk-mironov/78ccae01c3f8797adffeaeb4cb37794c to your computer and use it in GitHub Desktop.
Databinding with DelegatedProperties
class AccountViewModel : ObservableModel by ObservableModelDelegate() {
@get:Bindable var name by property<CharSequence>("", BR.name)
@get:Bindable var authenticated by property(false, BR.authenticated)
@get:Bindable var avatar by property("", BR.avatar)
}
import android.databinding.Observable
import android.databinding.PropertyChangeRegistry
fun ObservableModel.notifyPropertyChanged(fieldId: Int) = notifyPropertyChanged(this, fieldId)
fun ObservableModel.notifyChange() = notifyChange(this)
interface ObservableModel : Observable {
fun notifyPropertyChanged(container: Observable, fieldId: Int)
fun notifyChange(container: Observable)
}
class ObservableModelDelegate : ObservableModel {
@Transient private var callbacks: PropertyChangeRegistry? = null
@Synchronized override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback) {
if (callbacks == null) {
callbacks = PropertyChangeRegistry()
}
callbacks!!.add(callback)
}
@Synchronized override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback) {
callbacks?.remove(callback)
}
@Synchronized override fun notifyChange(container: Observable) {
callbacks?.notifyCallbacks(container, 0, null)
}
@Synchronized override fun notifyPropertyChanged(container: Observable, fieldId: Int) {
callbacks?.notifyCallbacks(container, fieldId, null)
}
}
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
fun <T> ObservableModel.property(initial: T, fieldId: Int, vararg additionalFieldIds: Int): ReadWriteProperty<Any, T> {
return ObservableModelProperty(initial, this, fieldId, additionalFieldIds)
}
internal abstract class BaseObservableModelProperty<T>(
private val observableModel: ObservableModel,
private val fieldId: Int,
private val additionalFieldIds: IntArray
) : ReadWriteProperty<Any, T> {
protected abstract var current: T
override fun getValue(thisRef: Any, property: KProperty<*>): T {
return current
}
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
if (current != value) {
current = value
observableModel.notifyPropertyChanged(fieldId)
additionalFieldIds.forEach {
observableModel.notifyPropertyChanged(it)
}
}
}
}
internal class ObservableModelProperty<T>(
initial: T,
observableModel: ObservableModel,
fieldId: Int,
additionalFieldIds: IntArray
) : BaseObservableModelProperty<T>(observableModel, fieldId, additionalFieldIds) {
override var current = initial
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment