https://kotlinlang.org logo
#android-architecture
Title
# android-architecture
u

ursus

12/05/2019, 7:12 AM
Which way of rendering sealed class hierarchy do you prefer?
1️⃣ 3
e

Edgars

12/05/2019, 7:22 AM
I prefer the first style, but I would extract them into separate methods, e.g.,
Copy code
when (state) {
    is Loading -> showLoadingState()
    is Success -> showSuccessState(state)
    is Error -> showErrorState(state)
}
u

ursus

12/05/2019, 7:29 AM
I also for some reason like the 1 even thought its more dangerous. Any reason why its like that for you? arent you biased because its only 3 states? Imagine 5, youd need to put same GONE code in 4 and the VISIBLE in 1
e

Edgars

12/05/2019, 7:35 AM
I don't see a problem with that in and of itself. If two of the states have some similarities (e.g., they both hide (some of) the same views), I'd extract that showing or hiding to a separate function and call it from both of the states.
I like 1️⃣, because that way whatever needs to happen for a state is written in that function. 2️⃣ can have a bug where you override some properties after checking the n-th state:
Copy code
// assume state is Success
if (state is Success) {
    // whatever
    some_view.isVisible = true
} else {
    some_view.isVisible = false
}

if (state is Error) { // state is not Error
    // whatever
} else {
    // some_view.isVisible = false
}
As a result,
some_view
will be hidden, even though we're in the
Success
state and want to show that view.
u

ursus

12/05/2019, 7:44 AM
Hmm..for that example I agree with you, but imagine this
Copy code
fun View.renderState1(state) {
    when(state) {
        is Loading -> {
            progressBar.visibility = View.VISIBLE
            errorView.visibility = View.GONE
            contentView.visibility = View.GONE
            whateEverView.visibility = View.GONE
            somethingView.visibility = View.GONE
        }
        is Success -> {
            progressBar.visibility = View.GONE
            errorView.visibility = View.GONE
            contentView.visibility = View.VISIBLE
            contentView.setData(state.data)
            whateEverView.visibility = View.GONE
            somethingView.visibility = View.GONE
        }
        is Error -> {
            progressBar.visibility = View.GONE
            errorView.visibility = View.VISIBLE
            errorView.setErrorMessage(state.errorMessage)
            contentView.visibility = View.GONE
            whateEverView.visibility = View.GONE
            somethingView.visibility = View.GONE
        }
        is Whatever -> {
            progressBar.visibility = View.GONE
            errorView.visibility = View.VISIBLE
            errorView.setErrorMessage(state.errorMessage)
            contentView.visibility = View.GONE
            whateEverView.visibility = View.VISIBILE
            somethingView.visibility = View.GONE
        }
        is Something -> {
            progressBar.visibility = View.GONE
            errorView.visibility = View.VISIBLE
            errorView.setErrorMessage(state.errorMessage)
            contentView.visibility = View.GONE
            whateEverView.visibility = View.GONE
            somethingView.visibility = View.VISIBLE
        }
    }
}
it doesnt scale
☝️ 1
(I might have messed up the values, but basically one thing is turned on for one case)
e

Edgars

12/05/2019, 8:05 AM
First of all, I'd extract each
when
case to its own function (as in the snippet I posted). Then, if all of the cases work with the same bunch of views, you could have something like:
Copy code
fun showViews(content: Boolean = false, error: Boolean = false, something: Boolean = false) {
    content.isVisible = content
    error.isVisible = error
    // ...
}
that you would call like
showViews(error = true)
.
u

ursus

12/05/2019, 8:49 AM
that would not be so handy since you will need payloads there as well, not only booleans
👍 1
e

Edgars

12/05/2019, 9:49 AM
You would need to mix-and-match that. Use that for showing/hiding views and then work with your payloads in each state function.
Copy code
when (state) {
    is Success -> {
        showViews(content = true)
        // update UI content here
    }
    // ...
}
Personally, I wouldn't be too worried about having
someView.isVisible = false
in each of the
showFooState()
functions, but that's just me.
r

Rodrigo Fonseca

12/05/2019, 1:27 PM
a good option to complement would be using
viewflipper
s

Steve

12/05/2019, 5:24 PM
I think having a method
showLoadingState()
where you just list off all the views and explicitly set their visibility state, among other things, isn't bad
as long as the visibility/state of the views isn't manipulated outside of those functions
👍 2
6 Views