我的活动signUpClient.kt
调用API类,将EditText文本发送到API(在称为客户端的模型内):
signUpAPI.postClient(client)
在此API中,有一个用于发布客户端的函数(下面的代码)。 只要给定的电子邮件已经存在,服务器就会返回错误消息。我可以通过Toast显示错误,并传递正确的上下文。
问题是:我想向用户指示字段email
不正确,更改了其EditText的属性。
我试图通过API访问它的ID,但它无法访问它。
有什么办法吗?
注意:我知道如何更改EditText属性,问题是如何从另一个类(甚至不是活动)更改它。 我尝试使用
findViewById
失败。
signup_client.kt:
btn_signup.setOnClickListener() {
val name = et_name.text.toString()
val email = et_email.text.toString()
val cellphone = et_cellphone.text.toString()
val birthdate = et_birthdate.text.toString()
val password = et_password.text.toString()
// Constructs a new client object
val client = Client(
name,
email,
cellphone,
birthdate,
password
)
signUpAPI = API(this)
signUpAPI.postCliente(client)
}
API.kt:
fun postCliente(cliente: Cliente) {
val TAG = "API Activity"
val apiInterface: ApiInterface
apiInterface = ClientApi.getClient().create(ApiInterface::class.java)
val clientePostCall = apiInterface.postCliente(cliente)
mProgressBar.visibility = View.VISIBLE
clientePostCall.enqueue(object: Callback<Cliente> {
override fun onResponse(call: Call<Cliente>, response: Response<Cliente>) {
mProgressBar.visibility = View.GONE
if(response.isSuccessful){
try {
Toast.makeText(context,"User " + response.body()!!.name + " created successfully.",Toast.LENGTH_SHORT).show()
val backHomeIntent = Intent(context, MainActivity::class.java)
context.startActivity(backHomeIntent)
} catch (e: NullPointerException) {
Toast.makeText(context, "Problem is unknown: ", Toast.LENGTH_SHORT).show()
}
}else {
try {
var jObjError = JSONObject(response.errorBody()!!.string())
var email = jObjError.getString("client_email")
Toast.makeText(context, "Email " + email + " já existe.", Toast.LENGTH_SHORT).show()
} catch (e: IOException){
Toast.makeText(context, "Problem is unknown: ", Toast.LENGTH_SHORT).show()
}
}
}
override fun onFailure(call: Call<Cliente>, t: Throwable) {
mProgressBar.visibility = View.GONE
Log.e(TAG, "onFailure: " + t.localizedMessage)
}
})
}
答案 0 :(得分:0)
您可以定义一个枚举,该枚举说明发生了哪种错误,如下所示:
enum class ApiError {
EMAIL_EXISTS, UNKNOWN
}
然后您的postClient函数将一个函数作为参数:
fun postClient(client: Client, errorCallback: (ApiError, String) -> Unit)
一旦到达任何故障点,就可以调用此函数,例如:
errorCallback(ApiError.EMAIL_EXISTS, "The email already exists")
,当您调用postClient函数时,您可以这样做:
postClient(client) { errorType, text ->
if (errorType == ApiError.EMAIL_EXISTS) {
emailErrorEditText.text = text
}
}
如果您遇到更多情况,则适合使用when statement。将函数作为参数的概念属于高阶函数的范围。您可以阅读有关它们的更多信息here。它们真的非常有用。
答案 1 :(得分:0)
理想情况下,您不应该具有在API回调中访问您的视图的代码,并防止这些视图引用使您的Activity超出预期的生命周期。您还希望保持您的网络代码和查看代码完全脱钩。
您所能做的就是用一个LiveData字段实现一个ViewModel类,该字段保存UI的状态(包括错误)。然后,您的活动可以观察这些LiveData字段并更新视图。在ViewModel中,您还可以让您的API类执行实际的API类,其回调将更新ViewModel的LiveData字段。
如需更多信息,请参阅Android文档中的内容: https://developer.android.com/topic/libraries/architecture/viewmodel
https://developer.android.com/topic/libraries/architecture/livedata