Extending the View

| Colin Dodd

Now you see me, now you don't. Improving Android visibility with Kotlin extension functions

Extension functions are one of the most powerful features of Kotlin. They allow for classes to be extended with your own logic no matter how locked down the class is.

This gave me the opportunity to fix one of my personal pet peeves in Android.

Views have three states of visibility. VISIBLE, the view can be seen. INVISIBLE, the view can not be seen but it takes up the same amount of space as it would have done were it visible. GONE, the view can not be seen and it takes up no space.

So many times I have ended up in a situation where I want to set the visibility of a view based on the state of a boolean.

if (isLoggedIn) {
    button.visibility = View.VISIBLE
} else {
    button.visibility = View.GONE
}

Since views have three states there is no easy say to just map a boolean to visibility state. There is no setVisibility(true) -- there has always had to be some wrapping logic. Well now that extension functions exist I can fix that once and for all:

private fun View.isVisible(shouldShow: Boolean) {
    visibility = if (shouldShow) View.VISIBLE else View.GONE
}

private fun example() {
    button.isVisible(isLoggedIn)
}

Finally! Now I can just call isVisible on any view with a boolean and the visibility of the view will be set to either VISIBLE or GONE. Of course, if you actually want views to become INVISIBLE, then you'll need a second extension function. Or you could give your extension function a default argument:

private fun View.isVisible(bool: Boolean?, nonVisibleState: Int = View.GONE) {
    visibility = if (bool == true) View.VISIBLE else nonVisibleState
}

private fun example() {
    // this defaults to View.GONE
    button1.isVisible(isLoggedIn)

    // this uses View.INVISIBLE
    button2.isVisible(isLoggedIn, View.INVISIBLE)
}