Home > Software engineering >  Kotlin multiple when statement
Kotlin multiple when statement

Time:12-30

I am learning to build a simple android app with android studio and i created a function to find the id of some values. While writing this function I thought using when statement (Kotlin) but a sadly had to repeat it. Is there a way to assign the result of a when statement to multiple variables at the same time? In other language I would just have returned a list which I would have disassembled but I can't find a way to do it in Kotlin. It's not really big problem but I like optimizing my code.

// my Kotlin function
// setting a specific state
private fun setState(num: Int) {
    Log.v(TAG, num.toString())
    // get the correct image id
    val imageId: Int? = when (num) {
        0 -> R.drawable.lemon_restart
        1 -> R.drawable.lemon_tree
        2 -> R.drawable.lemon_squeeze
        3 -> R.drawable.lemon_drink
        else -> null
    }
    // get the correct text to show
    val txtId: Int? = when (num) {
        0 -> R.string.txt_state_0
        1 -> R.string.txt_state_1
        2 -> R.string.txt_state_2
        3 -> R.string.txt_state_3
        else -> null
    }
    // get the correct content description for accessibility
    val contentDescriptionId: Int? = when (num) {
        0 -> R.string.lemon_restart_description
        1 -> R.string.lemon_tree_description
        2 -> R.string.lemon_squeeze_description
        3 -> R.string.lemon_drink_description
        else -> null
    }
    // setting the new stuff
    val imView: ImageView = findViewById(R.id.imageState)
    val txtView: TextView = findViewById(R.id.textOrder)
    txtView.text = getString(txtId!!)
    imView.setImageResource(imageId!!)
    imView.contentDescription = getString(contentDescriptionId!!)
}

feel free to optimize it as much as possible

CodePudding user response:

You can return Triple or your own data class from when, and then destructure it:

val (imageId, txtId, contentDescriptionId) = when (num) {
    0 -> Triple(R.drawable.lemon_restart, R.string.txt_state_0, R.string.lemon_restart_description)
    ...
    else -> Triple(null, null, null)
}

CodePudding user response:

Since every field is constant and states are fixed. you can make the states as constant. to decouple code little bit you can create a separate class to return the values for particular state. below is an Example :

class StateHandle private constructor(imageId: Int?, txtId: Int?, contentDescriptionId: Int?) {
    companion object {
        private val imageIds = arrayOf(
            R.drawable.lemon_restart,
            R.drawable.lemon_tree,
            R.drawable.lemon_squeeze,
            R.drawable.lemon_drink
        )
        private val txtIds = arrayOf(
            R.string.txt_state_0,
            R.string.txt_state_1,
            R.string.txt_state_2,
            R.string.txt_state_3
        )
        private val contentIds = arrayOf(
            R.string.lemon_restart_description,
            R.string.lemon_tree_description,
            R.string.lemon_squeeze_description,
            R.string.lemon_drink_description
        )

        @JvmStatic
        fun getStateFor(num: Int): StateHandle {
            return StateHandle(
                imageIds.getOrNull(num), txtIds.getOrNull(num),
                imageIds.getOrNull(num)
            )
        }
    }
}

Its not perfect but it is a bit more reusable . just call #getStateFor and use the StateHandle object .

  • Related