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: 这是我的第一个回答,不当之处还请见谅。