Reputation: 1107
I'm trying to get started with Android development using Kotlin. Part of what I'm trying to do is send an HTTP request from my login activity and take appropriate action from the response. I'm using Fuel for this.
When the "Sign in" button is tapped, I'm calling the following fun
:
private fun disableInput() {
username_input.isEnabled = false
password_input.isEnabled = false
sign_in_button.isEnabled = false
login_progress.visibility = View.VISIBLE
}
This works fine. I then make my HTTP request:
"http://my.login.url.com".httpPost()
.header("Content-Type" to "application/json")
.body(json, Charsets.UTF_8)
.response(AuthorizationSuccess.Deserializer()) { _, response, result ->
val (auth, error) = result
if (error != null || auth == null) {
Snackbar.make(view, "Error", 0).show()
enableInput()
} else {
// Handle the response
}
}
The problem is that when I receive an error, I can't seem to re-enable the UI. The Snack
is shown and enableInput
is called:
private fun enableInput() {
username_input.isEnabled = true
password_input.isEnabled = true
sign_in_button.isEnabled = true
login_progress.visibility = View.GONE
}
However, it hits only the first line (username_input.isEnabled = true
) and goes no further. It does enable the username input so I know the assignment is succeeding, but I can't figure out why it doesn't proceed to enable the rest of the UI.
I suspect it has something to do with the fact that I'm calling it from an asynchronous operation, but I haven't been able to find any other way to do it.
Is there a special way I ought to be calling enableInput
, or is this completely the wrong way to go about it?
Upvotes: 1
Views: 193
Reputation: 13690
UI code must run in the UI Thread in Android.
The disableInput
function runs in response to a button click, so it is already in the UI Thread, but when you handle the HTTP response, Fuel will run your callback in a different Thread.
To change back to the UI Thread to update your UI components, use View::post
, something like this:
private fun enableInput() {
username_input.post {
username_input.isEnabled = true
password_input.isEnabled = true
sign_in_button.isEnabled = true
login_progress.visibility = View.GONE
}
}
As I said in the comments, in Kotlin, it's also a convention to use camelCase, so instead of username_input
, use usernameInput
.
Upvotes: 2