Careeroza
Custom Property Delegates
getValue and setValue
Any class with operator fun getValue (and setValue for var) can be a delegate. The standard interface ReadWriteProperty<Owner, T> gives the right signatures.
Example
A delegate that trims and capitalises names, and one that remembers a history of values.
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class Trimmed : ReadWriteProperty<Any?, String> {
private var value = ""
override fun getValue(thisRef: Any?, property: KProperty<*>) = value
override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
this.value = value.trim().split(" ").filter { it.isNotEmpty() }
.joinToString(" ") { it.lowercase().replaceFirstChar(Char::uppercase) }
}
}
class History<T>(initial: T) {
val values = mutableListOf(initial)
operator fun getValue(thisRef: Any?, property: KProperty<*>): T = values.last()
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { values += value }
}
class Student {
var fullName by Trimmed()
val gradeHistory = History("C")
var grade by gradeHistory
}
fun main() {
val s = Student()
s.fullName = " rAHUL kumar "
println("'${s.fullName}'")
s.grade = "B"
s.grade = "A"
println("Grade: ${s.grade}, history: ${s.gradeHistory.values}")
}Output
'Rahul Kumar' Grade: A, history: [C, B, A]
Where You See Delegates in Android
class ProfileFragment : Fragment() {
private val viewModel: ProfileViewModel by viewModels() // lazy ViewModel
private val args: ProfileFragmentArgs by navArgs() // Navigation safe args
}
@Composable
fun Counter() {
var count by remember { mutableStateOf(0) } // State<T> delegate
Button(onClick = { count++ }) { Text("Clicked $count times") }
}
val Context.dataStore by preferencesDataStore(name = "settings") // DataStore