Red wine
Red wine

Reputation: 172

Kotlin make an instance of a class and implement a callback in one line of code

I am new to Kotlin and have managed to modify my Java timer class so that I can implement it with two lines of code.

I wonder if there is some way to perhaps modify it and so implement it with one line of code? Thanks for any suggestions.

Two lines implementation:

fun testTimer() {
    var tmr = MyTimer(1000, true)
    tmr.onTimer = { doSometing() }
}

Timer class

class MyTimer {
    private var running = false
    private var repeatDelayMS: Int = 0
    private val handler = Handler()
    var onTimer:()-> Unit = {}

    private val runnable = object : Runnable {
        override fun run() {
            if (running) {
                onTimer()
                if (repeatDelayMS > 0)
                    handler.postDelayed(this, repeatDelayMS.toLong())
                else
                    stop()
            }
        }
    }

    constructor(repeatDelayMS: Int, runOnCreate: Boolean) {
        this.repeatDelayMS = repeatDelayMS
        if (runOnCreate)
            start()
    }

    fun start() {
        running = true
        handler.postDelayed(runnable, repeatDelayMS.toLong())
    }


    fun stop() {
        running = false
        handler.removeCallbacks(runnable)
    }
}

Upvotes: 1

Views: 590

Answers (2)

Tohu
Tohu

Reputation: 151

You could do

val tmr = MyTimer(1000, true).apply {
    onTimer = { doSomething() }
}

Upvotes: 3

marianosimone
marianosimone

Reputation: 3606

Given your interface, you can probably move your properties declaration to a primary constructor, and the start() to an init block.

Also note that val over var gives you immutable/read-only properties

// this is not one line now, but just for formatting purposes ;)
fun testTimer() {
    val timer = MyTimer(
            repeatDelayMS = 1000,
            runOnCreate = true,
            onTimer = { doSomething() }
    )
}

class MyTimer(
        private var running: Boolean = false,
        private val runOnCreate: Boolean,
        private val repeatDelayMS: Int = 0,
        private val handler: Handler = Handler(),
        private val onTimer: () -> Unit = {}
) {

    init {
        if (runOnCreate) {
            start()
        }
    }

    // the rest is the same
}

Upvotes: 2

Related Questions