【问题标题】:Text Data binding doesn't work in Retrofit2 callback文本数据绑定在 Retrofit2 回调中不起作用
【发布时间】:2020-09-07 15:25:48
【问题描述】:

登录成功后我会显示用户名。

    private fun getInfo(context: Context, userkey: String){
        binding!!.initVm!!.username = "Hello, boo1"

        ServiceGenerator
                .createService(Service::class.java)!!
                .getUserInfo(userkey)
                .enqueue(object : Callback<UserInfo> {
                    override fun onFailure(call: Call<UserInfo>, t: Throwable) {
                        binding!!.initVm!!.username = "Hello, boo5"
                    }

                    override fun onResponse(call: Call<UserInfo>, response: Response<UserInfo>) {
                        val result = response.body()!!
                        if (response.isSuccessful){
                            Log.d("test", "Hello, ${response.body()!!.username}")
                            binding!!.initVm!!.username = "Hello, boo2"
                        }else{
                            binding!!.initVm!!.username = "Hello, boo3"
                        }
                    }
                })
    }
    <TextView
        android:id="@+id/tv_greeting"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:text="@{initVm.username}"
        android:visibility="@{initVm.greetingVisibility}"
        android:textStyle="bold"/>

即使网络通信成功,也不绑定数据。所以,它显示“你好,boo1”。这很奇怪。会因为 Asyc 而发生吗?我该如何解决这个问题?

我可以通过访问 View 来插入文本。但我不想这样做,我想使用绑定。

class  InitViewModel(handler: InitHandler) : ViewModel() {
    var handler = handler
    var greetingVisibility = View.VISIBLE
    var logInVisibility = View.VISIBLE
    var username = "Hello, N/A"
    // ... methods
}

【问题讨论】:

  • 这是什么initVm
  • @AbrahamMathew 已更新。我认为这没关系,因为Hello, boo1 工作正常。
  • 您正在调用 getInfo() 并且您的值已更新为 Hello, boo1,但您没有遇到成功或失败。如果成功,那么它会改变
  • 这种方法也不好。您可以在 viewmodel livedata 变量中设置从 api 获取的详细信息,并可以轻松地在片段/活动中显示它

标签: android data-binding android-mvvm


【解决方案1】:

我不认为这是因为异步。而是因为您的 username 是不可观察的,因此其更改不会影响您的 UI。

通过在 ViewModel 中绑定您的 username var 来更新 UI 应该是可观察的 - LiveData(在这种情况下不需要显式观察它 - DataBinding 框架会为您完成)或 @987654321 @

如果您选择 LiveData,您应该在 Fragment|Activity 中设置新值:

binding!!.initVm!!.username.value = "Hello, boo2"

之后 UI 将被更新

【讨论】:

  • 那么,您能解释一下为什么Hello, boo1 有效吗?而且我不使用 LiveData。
  • 我猜你在初始化绑定变量后调用 getInfo ?仅用于测试 - 尝试使用处理程序延迟此“Hello,boo1”设置(一秒钟就足够了)并检查结果是否相同。
  • 我的意思是“binding.initVm = yourViewModel”和“getInfo”调用之间的时间是什么?第二个在第一个之后还是在它之前开始?
  • 我在onCreateView() 中初始化binding 并在onResume() 中调用getInfo()。所以,没关系。而且,Hello, boo1 已经设置好了(用户名本身在设置之前有Hello, N/A)没有任何问题。所以,这没有意义。它应该在之后工作。
  • 好吧,我给了你两种实验方法: 1. 使用 ObservableField 作为用户名的类型(如果你反对 LiveData)。 2. 使用 Handler 将您设置的用户名延迟 1 秒。你能试试吗?首先应该解决问题,其次 - 解释(以某种方式)您的用例。如果两个实验都失败了,其他人可能会排除这种情况,为您提供更可靠的建议。
猜你喜欢
  • 1970-01-01
  • 2017-11-27
  • 2013-12-29
  • 1970-01-01
  • 2015-01-29
  • 2014-05-11
  • 2015-08-12
  • 2015-10-14
  • 2014-12-16
相关资源
最近更新 更多