Kotlin LocalBroadcastManager 在 UI 上调用显示值后无法工作
Kotlin LocalBroadcastManager not working after call to display values on UI
我有一个正在处理的 android 应用程序,我在其中使用 Volley 发出 API 请求,在发出 API 调用后,我得到一堆 JSON 对象返回。我现在将这些值保存为默认值。保存后,我现在尝试将值显示到我的 ui 元素中,但一切都是空白的,并且不显示值。我的代码在下面突出显示
fun loginUser(context: Context, email: String, password: String, completion: (Boolean) -> Unit): Unit {
val jsonBody = JSONObject()
jsonBody.put("email", email)
jsonBody.put("password", password)
val requestBody = jsonBody.toString()
val loginRequest = object : JsonObjectRequest(Method.POST, URL_LOGIN, null, Response.Listener {response ->
try {
userEmail = response.getString("user")
authToken = response.getString("token")
isLoggedIn = true
completion(true)
} catch (e: JSONException) {
Log.d("JSON", "EXC:" + e.localizedMessage)
completion(false)
}
}, Response.ErrorListener { error ->
Log.d("ERROR", "Could not login user: $error")
completion(false)
}) {
override fun getBodyContentType(): String {
return "application/json; charset=utf-8"
}
override fun getBody(): ByteArray {
return requestBody.toByteArray()
}
}
Volley.newRequestQueue(context).add(loginRequest)
}
fun findUserByEmail(context: Context, completion: (Boolean) -> Unit): Unit {
val finUserByEmailRequest = object : JsonObjectRequest(Method.GET, "$URL_GET_USER$userEmail", null, Response.Listener {response ->
try {
UserDataService.name = response.getString("name")
UserDataService.email = response.getString("email")
UserDataService.avatarName = response.getString("avatarName")
UserDataService.avatarColor = response.getString("avatarColor")
UserDataService.id = response.getString("_id")
val userDataChanaged = Intent(BROADCAST_USER_DATA_CHANGED)
LocalBroadcastManager.getInstance(context).sendBroadcast(userDataChanaged)
completion(true)
} catch (e: JSONException) {
Log.d("JSON", "EXC:" + e.localizedMessage)
completion(false)
}
}, Response.ErrorListener { error ->
Log.d("ERROR", "Could not find user: $error")
completion(false)
}) {
override fun getBodyContentType(): String {
return "application/json; charset=utf-8"
}
override fun getHeaders(): MutableMap<String, String> {
val headers = HashMap<String, String>()
headers["Authorization"] = "Bearer $authToken"
return headers
}
}
Volley.newRequestQueue(context).add(finUserByEmailRequest)
}
我的 MainActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
val toggle = ActionBarDrawerToggle(
this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
drawer_layout.addDrawerListener(toggle)
toggle.syncState()
LocalBroadcastManager.getInstance(this).registerReceiver(userDataChangeReceiver, IntentFilter(BROADCAST_USER_DATA_CHANGED))
}
private val userDataChangeReceiver = object : BroadcastReceiver() {
override fun onReceive(contect: Context?, intent: Intent?) {
if (AuthService.isLoggedIn) {
userNameNavHeader.text = UserDataService.name
userEmailNavHeader.text = UserDataService.email
val resourceId = resources.getIdentifier(UserDataService.avatarName, "drawable", packageName)
userImageNavHeader.setImageResource(resourceId)
userImageNavHeader.setBackgroundColor(UserDataService.returnAvatarColor(UserDataService.avatarColor))
loginBtnNavHeader.text = "Logout"
}
}
}
调用 loginUser 方法的地方
fun loginLoginBtnClicked(view: View): Unit {
val email = loginEmailTxt.text.toString()
val password = loginPasswordTxt.text.toString()
AuthService.loginUser(this, email, password) {success ->
if (success) {
AuthService.findUserByEmail(this) {fsuccess ->
if (fsuccess) {
finish()
}
}
}
}
}
您首先需要获取对nav_header_main 布局的引用,以便能够更新nav_header_main 中的text-View 和image-view。与其直接使用元素的 id,不如使用 nav_header 引用然后像这样使用 id
private val userDataChangeReceiver = object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if(AuthService.isLoggedIn){
Log.d("qwe", UserDataService.name)
Log.d("qwe", UserDataService.email)
Log.d("qwe", UserDataService.avatarName)
Log.d("qwe", "Made it inside the broadcast bro")
Log.d("qwe", "Wrap")
nav_drawer_header_include.userEmailNavHeader.text = UserDataService.email
nav_drawer_header_include.userNameNavHeader.text = UserDataService.name
userEmailNavHeader.text = UserDataService.email
val resourseid= resources.getIdentifier(UserDataService.avatarName,"drawable",packageName)
nav_drawer_header_include.userImageNavHeader.setImageResource(resourseid)
nav_drawer_header_include.loginBtnNavHeader.text="Logout"
}
}
}
我们应该最常使用 Log,它帮助我直接解决问题,而不是把时间浪费在完美的工作上。
我在学习 Android Kotlin 课程时也偶然发现了这个问题,但在搜索之后我发现很多人都遇到过这个问题,他们在不同的平台上提问但没有提供答案。但是在搜索相同的术语后 "UI elements not updating android" 在 java
中找到了一些堆栈溢出答案
他们都解释说要先获取参考,然后我们才能更新视图。然后我尝试了,幸运的是它工作得很好。
PS: 这是我的第一个回答,不当之处还请见谅。
我有一个正在处理的 android 应用程序,我在其中使用 Volley 发出 API 请求,在发出 API 调用后,我得到一堆 JSON 对象返回。我现在将这些值保存为默认值。保存后,我现在尝试将值显示到我的 ui 元素中,但一切都是空白的,并且不显示值。我的代码在下面突出显示
fun loginUser(context: Context, email: String, password: String, completion: (Boolean) -> Unit): Unit {
val jsonBody = JSONObject()
jsonBody.put("email", email)
jsonBody.put("password", password)
val requestBody = jsonBody.toString()
val loginRequest = object : JsonObjectRequest(Method.POST, URL_LOGIN, null, Response.Listener {response ->
try {
userEmail = response.getString("user")
authToken = response.getString("token")
isLoggedIn = true
completion(true)
} catch (e: JSONException) {
Log.d("JSON", "EXC:" + e.localizedMessage)
completion(false)
}
}, Response.ErrorListener { error ->
Log.d("ERROR", "Could not login user: $error")
completion(false)
}) {
override fun getBodyContentType(): String {
return "application/json; charset=utf-8"
}
override fun getBody(): ByteArray {
return requestBody.toByteArray()
}
}
Volley.newRequestQueue(context).add(loginRequest)
}
fun findUserByEmail(context: Context, completion: (Boolean) -> Unit): Unit {
val finUserByEmailRequest = object : JsonObjectRequest(Method.GET, "$URL_GET_USER$userEmail", null, Response.Listener {response ->
try {
UserDataService.name = response.getString("name")
UserDataService.email = response.getString("email")
UserDataService.avatarName = response.getString("avatarName")
UserDataService.avatarColor = response.getString("avatarColor")
UserDataService.id = response.getString("_id")
val userDataChanaged = Intent(BROADCAST_USER_DATA_CHANGED)
LocalBroadcastManager.getInstance(context).sendBroadcast(userDataChanaged)
completion(true)
} catch (e: JSONException) {
Log.d("JSON", "EXC:" + e.localizedMessage)
completion(false)
}
}, Response.ErrorListener { error ->
Log.d("ERROR", "Could not find user: $error")
completion(false)
}) {
override fun getBodyContentType(): String {
return "application/json; charset=utf-8"
}
override fun getHeaders(): MutableMap<String, String> {
val headers = HashMap<String, String>()
headers["Authorization"] = "Bearer $authToken"
return headers
}
}
Volley.newRequestQueue(context).add(finUserByEmailRequest)
}
我的 MainActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
val toggle = ActionBarDrawerToggle(
this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
drawer_layout.addDrawerListener(toggle)
toggle.syncState()
LocalBroadcastManager.getInstance(this).registerReceiver(userDataChangeReceiver, IntentFilter(BROADCAST_USER_DATA_CHANGED))
}
private val userDataChangeReceiver = object : BroadcastReceiver() {
override fun onReceive(contect: Context?, intent: Intent?) {
if (AuthService.isLoggedIn) {
userNameNavHeader.text = UserDataService.name
userEmailNavHeader.text = UserDataService.email
val resourceId = resources.getIdentifier(UserDataService.avatarName, "drawable", packageName)
userImageNavHeader.setImageResource(resourceId)
userImageNavHeader.setBackgroundColor(UserDataService.returnAvatarColor(UserDataService.avatarColor))
loginBtnNavHeader.text = "Logout"
}
}
}
调用 loginUser 方法的地方
fun loginLoginBtnClicked(view: View): Unit {
val email = loginEmailTxt.text.toString()
val password = loginPasswordTxt.text.toString()
AuthService.loginUser(this, email, password) {success ->
if (success) {
AuthService.findUserByEmail(this) {fsuccess ->
if (fsuccess) {
finish()
}
}
}
}
}
您首先需要获取对nav_header_main 布局的引用,以便能够更新nav_header_main 中的text-View 和image-view。与其直接使用元素的 id,不如使用 nav_header 引用然后像这样使用 id
private val userDataChangeReceiver = object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if(AuthService.isLoggedIn){
Log.d("qwe", UserDataService.name)
Log.d("qwe", UserDataService.email)
Log.d("qwe", UserDataService.avatarName)
Log.d("qwe", "Made it inside the broadcast bro")
Log.d("qwe", "Wrap")
nav_drawer_header_include.userEmailNavHeader.text = UserDataService.email
nav_drawer_header_include.userNameNavHeader.text = UserDataService.name
userEmailNavHeader.text = UserDataService.email
val resourseid= resources.getIdentifier(UserDataService.avatarName,"drawable",packageName)
nav_drawer_header_include.userImageNavHeader.setImageResource(resourseid)
nav_drawer_header_include.loginBtnNavHeader.text="Logout"
}
}
}
我们应该最常使用 Log,它帮助我直接解决问题,而不是把时间浪费在完美的工作上。
我在学习 Android Kotlin 课程时也偶然发现了这个问题,但在搜索之后我发现很多人都遇到过这个问题,他们在不同的平台上提问但没有提供答案。但是在搜索相同的术语后 "UI elements not updating android" 在 java
他们都解释说要先获取参考,然后我们才能更新视图。然后我尝试了,幸运的是它工作得很好。
PS: 这是我的第一个回答,不当之处还请见谅。