Pramod Garg
Pramod Garg

Reputation: 2313

Can't use custom getter with delegated property

I am new to kotlin and can't figure out this issue.

I have a property that is not nullable and may or may not be used. Hence I have delegated it in a lazy way so that it is initialized when required.

private val labelAnimator: ObjectAnimator by lazy {
    ObjectAnimator.ofFloat(this, "floatingLabelFraction", 0f, 1f)
}

However, I also need to set some property of that object every time it is accessed.

fun getLabelAnimator(): ObjectAnimator {
    labelAnimator.duration = (if (isFloatingLabelAnimating) 300 else 0).toLong()
    return labelAnimator
}

But I cannot use a custom getter since the property is delegated. How do I achieve this in best possible way?

Upvotes: 3

Views: 2245

Answers (3)

Vlad
Vlad

Reputation: 8553

The shortest version

private val labelAnimator: ObjectAnimator by lazy {
    ObjectAnimator.ofFloat(this, "floatingLabelFraction", 0f, 1f).apply {
        duration = if (isFloatingLabelAnimating) 300L else 0L
    }
}

Upvotes: 0

tynn
tynn

Reputation: 39843

You could for example use your original property as Backing Property and actually define the property as a delegation to it.

private val _labelAnimator by lazy {
    ObjectAnimator.ofFloat(this, "floatingLabelFraction", 0f, 1f)
}

val labelAnimator: ObjectAnimator
    get() {
        _labelAnimator.duration = if (isFloatingLabelAnimating) 300L else 0L
        return _labelAnimator
    }

This gives you a getLabelAnimator() method in Java and direct property access in Kotlin.

But like it was stated several times before, it might not be the best way to implement such behavior. A simple factory could do the same with little overhead.

Upvotes: 5

Bozic Nebojsa
Bozic Nebojsa

Reputation: 3706

I am not a Kotlin expert, but it sounds wrong to me. By delegating to lazy you want to init object on its first getter call. And then, you are trying to write custom getter. I see a conflict there.

Maybe:

private val labelAnimator: ObjectAnimator by lazy {
    val labelAnimator = ObjectAnimator.ofFloat(this, "floatingLabelFraction", 0f, 1f)
    labelAnimator.duration = (if (isFloatingLabelAnimating) 300 else 0).toLong()
    labelAnimator
}

Upvotes: 0

Related Questions